diff options
author | Alan Hourihane <alanh@fairlite.demon.co.uk> | 2000-09-22 18:14:54 +0000 |
---|---|---|
committer | Alan Hourihane <alanh@fairlite.demon.co.uk> | 2000-09-22 18:14:54 +0000 |
commit | 03d179a6940dca9b9df53a499c9e6b0f32288ec8 (patch) | |
tree | 6692c38700e4a8e36948a052966d641541d4eafd | |
parent | 74ca7e306e647307a45f8bce860713c06f9c9144 (diff) |
Import of XFree86 4.0.1d-pre
59 files changed, 1266 insertions, 956 deletions
diff --git a/bsd-core/drmP.h b/bsd-core/drmP.h index b62aff08..a60ddae2 100644 --- a/bsd-core/drmP.h +++ b/bsd-core/drmP.h @@ -25,7 +25,7 @@ * DEALINGS IN THE SOFTWARE. * * $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmP.h,v 1.58 1999/08/30 13:05:00 faith Exp $ - * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drmP.h,v 1.1 2000/06/17 00:03:28 martin Exp $ + * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmP.h,v 1.1 1999/09/25 14:37:59 dawes Exp $ * */ diff --git a/bsd/Imakefile b/bsd/Imakefile index 7d33c205..b3e5971b 100644 --- a/bsd/Imakefile +++ b/bsd/Imakefile @@ -1,5 +1,4 @@ XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/Imakefile,v 1.1 2000/06/17 00:03:28 martin Exp $ -XCOMM $PI$ #include <Server.tmpl> @@ -11,6 +10,17 @@ LinkSourceFile(xf86drm.h,$(XF86OSSRC)) LinkSourceFile(xf86_OSproc.h,$(XF86OSSRC)) LinkSourceFile(sigio.c,$(XF86OSSRC)/shared) +XCOMM Try to use the Linux version of the DRM headers. This avoids skew +XCOMM and missing headers. If there's a need to break them out, they +XCOMM can be re-added later. If not, they can be moved to somewhere more +XCOMM OS-independent and referenced from there. +LinkSourceFile(drm.h,$(XF86OSSRC)/linux/drm/kernel) +LinkSourceFile(i810_drm.h,$(XF86OSSRC)/linux/drm/kernel) +LinkSourceFile(mga_drm.h,$(XF86OSSRC)/linux/drm/kernel) +LinkSourceFile(r128_drm.h,$(XF86OSSRC)/linux/drm/kernel) +LinkSourceFile(sis_drm_public.h,$(XF86OSSRC)/linux/drm/kernel) + + XCOMM This is a kludge until we determine how best to build the XCOMM kernel-specific device driver. This allows us to continue XCOMM to maintain the single Makefile.bsd with kernel-specific diff --git a/bsd/drm/drmstat.c b/bsd/drm/drmstat.c index 48fb1b16..0ce76b01 100644 --- a/bsd/drm/drmstat.c +++ b/bsd/drm/drmstat.c @@ -25,7 +25,7 @@ * DEALINGS IN THE SOFTWARE. * * $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmstat.c,v 1.28 1999/08/04 18:12:11 faith Exp $ - * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/drmstat.c,v 1.1 2000/06/17 00:03:30 martin Exp $ + * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmstat.c,v 1.1 1999/09/25 14:37:59 dawes Exp $ * */ diff --git a/bsd/drm/proc.c b/bsd/drm/proc.c index 3f6616ef..12168aa3 100644 --- a/bsd/drm/proc.c +++ b/bsd/drm/proc.c @@ -25,7 +25,7 @@ * DEALINGS IN THE SOFTWARE. * * $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/proc.c,v 1.4 1999/08/20 15:36:46 faith Exp $ - * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/proc.c,v 1.1 2000/06/17 00:03:30 martin Exp $ + * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/proc.c,v 1.1 1999/09/25 14:38:02 dawes Exp $ * */ diff --git a/bsd/drm/sysctl.c b/bsd/drm/sysctl.c index a890abac..7c736abf 100644 --- a/bsd/drm/sysctl.c +++ b/bsd/drm/sysctl.c @@ -25,7 +25,7 @@ * DEALINGS IN THE SOFTWARE. * * $PI$ - * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/sysctl.c,v 1.1 2000/06/17 00:03:31 martin Exp $ + * $XFree86$ * */ @@ -25,7 +25,7 @@ * DEALINGS IN THE SOFTWARE. * * $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmP.h,v 1.58 1999/08/30 13:05:00 faith Exp $ - * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drmP.h,v 1.1 2000/06/17 00:03:28 martin Exp $ + * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmP.h,v 1.1 1999/09/25 14:37:59 dawes Exp $ * */ diff --git a/libdrm/xf86drm.c b/libdrm/xf86drm.c index 10c2222c..aa086758 100644 --- a/libdrm/xf86drm.c +++ b/libdrm/xf86drm.c @@ -596,7 +596,15 @@ int drmMap(int fd, drmSize size, drmAddressPtr address) { + static unsigned long pagesize_mask = 0; + if (fd < 0) return -EINVAL; + + if (!pagesize_mask) + pagesize_mask = getpagesize() - 1; + + size = (size + pagesize_mask) & ~pagesize_mask; + *address = mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, handle); if (*address == MAP_FAILED) return -errno; return 0; diff --git a/libdrm/xf86drmHash.c b/libdrm/xf86drmHash.c index 24b698cc..17089e44 100644 --- a/libdrm/xf86drmHash.c +++ b/libdrm/xf86drmHash.c @@ -25,7 +25,7 @@ * * Authors: Rickard E. (Rik) Faith <faith@valinux.com> * - * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmHash.c,v 1.3 2000/06/17 00:03:34 martin Exp $ + * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmHash.c,v 1.2 2000/02/23 04:47:23 martin Exp $ * * DESCRIPTION * diff --git a/libdrm/xf86drmRandom.c b/libdrm/xf86drmRandom.c index 9e1e9ee2..71ef1155 100644 --- a/libdrm/xf86drmRandom.c +++ b/libdrm/xf86drmRandom.c @@ -25,7 +25,7 @@ * * Authors: Rickard E. (Rik) Faith <faith@valinux.com> * - * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmRandom.c,v 1.4 2000/06/17 00:03:34 martin Exp $ + * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmRandom.c,v 1.3 2000/02/23 04:47:23 martin Exp $ * * DESCRIPTION * diff --git a/libdrm/xf86drmSL.c b/libdrm/xf86drmSL.c index dd634c30..f67434be 100644 --- a/libdrm/xf86drmSL.c +++ b/libdrm/xf86drmSL.c @@ -25,7 +25,7 @@ * * Authors: Rickard E. (Rik) Faith <faith@valinux.com> * - * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmSL.c,v 1.3 2000/06/17 00:03:34 martin Exp $ + * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmSL.c,v 1.2 2000/02/23 04:47:24 martin Exp $ * * DESCRIPTION * diff --git a/linux-core/Makefile.kernel b/linux-core/Makefile.kernel index e262213a..9f8b702d 100644 --- a/linux-core/Makefile.kernel +++ b/linux-core/Makefile.kernel @@ -1,53 +1,89 @@ +# $XFree86$ # # Makefile for the drm device driver. This driver provides support for # the Direct Rendering Infrastructure (DRI) in XFree86 4.x. # -# Note! Dependencies are done automagically by 'make dep', which also -# removes any old dependencies. DON'T put your own dependencies here -# unless it's something special (ie not a .c file). + +# drm.o is a fake target -- it is never built +# The real targets are in the module-list +O_TARGET := drm.o +module-list := gamma.o tdfx.o r128.o ffb.o mga.o i810.o +export-objs := $(patsubst %.o,%_drv.o,$(module-list)) + +# libs-objs are included in every module so that radical changes to the +# architecture of the DRM support library can be made at a later time. +# +# The downside is that each module is larger, and a system that uses +# more than one module (i.e., a dual-head system) will use more memory +# (but a system that uses exactly one module will use the same amount of +# memory). # -# Note 2! The CFLAGS definitions are now inherited from the -# parent makes.. +# The upside is that if the DRM support library ever becomes insufficient +# for new families of cards, a new library can be implemented for those new +# cards without impacting the drivers for the old cards. This is significant, +# because testing architectural changes to old cards may be impossible, and +# may delay the implementation of a better architecture. We've traded slight +# memory waste (in the dual-head case) for greatly improved long-term +# maintainability. # -# $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/Makefile.kernel,v 1.6 2000/06/17 00:03:34 martin Exp $ +lib-objs := init.o memory.o proc.o auth.o context.o drawable.o bufs.o +lib-objs += lists.o lock.o ioctl.o fops.o vm.o dma.o ctxbitmap.o -L_TARGET := libdrm.a +ifeq ($(CONFIG_AGP),y) + lib-objs += agpsupport.o +else + ifeq ($(CONFIG_AGP),m) + lib-objs += agpsupport.o + endif +endif -L_OBJS := init.o memory.o proc.o auth.o context.o drawable.o bufs.o \ - lists.o lock.o ioctl.o fops.o vm.o dma.o ctxbitmap.o \ - agpsupport.o +gamma-objs := $(lib-objs) gamma_drv.o gamma_dma.o +tdfx-objs := $(lib-objs) tdfx_drv.o tdfx_context.o +r128-objs := $(lib-objs) r128_drv.o r128_dma.o r128_context.o r128_bufs.o +ffb-objs := $(lib-objs) ffb_drv.o ffb_context.o +mga-objs := $(lib-objs) mga_drv.o mga_dma.o mga_context.o mga_bufs.o \ + mga_state.o +i810-objs := $(lib-objs) i810_drv.o i810_dma.o i810_context.o i810_bufs.o -M_OBJS := +obj-$(CONFIG_DRM_GAMMA) += gamma.o $(gamma-objs) +obj-$(CONFIG_DRM_TDFX) += tdfx.o $(tdfx-objs) +obj-$(CONFIG_DRM_R128) += r128.o $(r128-objs) +obj-$(CONFIG_DRM_FFB) += ffb.o $(ffb-objs) -ifdef CONFIG_DRM_GAMMA -M_OBJS += gamma.o +ifneq ($CONFIG_AGP),) +obj-$(CONFIG_DRM_MGA) += mga.o $(mga-objs) +obj-$(CONFIG_DRM_I810) += i810.o $(i810-objs) endif -ifdef CONFIG_DRM_TDFX -M_OBJS += tdfx.o -endif +# Take module names out of obj-y and int-m -ifdef CONFIG_DRM_MGA -M_OBJS += mga.o -endif +obj-y := $(filter-out $(module-list), $(obj-y)) +int-m := $(filter-out $(module-list), $(obj-m)) -ifdef CONFIG_DRM_R128 -M_OBJS += r128.o -endif +# Translate to Rules.make lists. + +O_OBJS := $(filter-out $(export-objs), $(obj-y)) +OX_OBJS := $(filter $(export-objs), $(obj-y)) +M_OBJS := $(sort $(filter $(module-list), $(obj-m))) +MI_OBJS := $(sort $(filter-out $(export-objs), $(int-m))) +MIX_OBJS := $(sort $(filter $(export-objs), $(int-m))) include $(TOPDIR)/Rules.make -gamma.o: gamma_drv.o gamma_dma.o $(L_TARGET) - $(LD) $(LD_RFLAG) -r -o $@ gamma_drv.o gamma_dma.o -L. -ldrm +gamma.o: $(gamma-objs) + $(LD) -r -o $@ $(gamma-objs) + +tdfx.o: $(tdfx-objs) + $(LD) -r -o $@ $(tdfx-objs) -tdfx.o: tdfx_drv.o tdfx_context.o $(L_TARGET) - $(LD) $(LD_RFLAG) -r -o $@ tdfx_drv.o tdfx_context.o -L. -ldrm +mga.o: $(mga-objs) + $(LD) -r -o $@ $(mga-objs) -i810.o: i810_drv.o i810_context.o $(L_TARGET) - $(LD) $(LD_RFLAG) -r -o $@ i810_drv.o i810_bufs.o i810_dma.o i810_context.o -L. -ldrm +i810.o: $(i810-objs) + $(LD) -r -o $@ $(i810-objs) -mga.o: mga_drv.o mga_context.o mga_dma.o mga_bufs.o $(L_TARGET) - $(LD) $(LD_RFLAG) -r -o $@ mga_drv.o mga_bufs.o mga_dma.o mga_context.o mga_state.o -L. -ldrm +r128.o: $(r128-objs) + $(LD) -r -o $@ $(r128-objs) -r128.o: r128_drv.o r128_context.o $(L_TARGET) - $(LD) $(LD_RFLAG) -r -o $@ r128_drv.o r128_context.o -L. -ldrm +ffb.o: $(ffb-objs) + $(LD) -r -o $@ $(ffb-objs) diff --git a/linux-core/README.drm b/linux-core/README.drm index 1cc4c277..b48b7b67 100644 --- a/linux-core/README.drm +++ b/linux-core/README.drm @@ -1,3 +1,9 @@ +/* $XFree86$ */ + +************************************************************ +* For the very latest on DRI development, please see: * +* http://dri.sourceforge.net/ * +************************************************************ The Direct Rendering Manager (drm) is a device-independent kernel-level device driver that provides support for the XFree86 Direct Rendering @@ -36,6 +42,7 @@ For specific information about kernel-level support, see: A Security Analysis of the Direct Rendering Infrastructure http://precisioninsight.com/dr/security.html - - -$XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/README.drm,v 1.2 1999/09/27 14:59:24 dawes Exp $ +************************************************************ +* For the very latest on DRI development, please see: * +* http://dri.sourceforge.net/ * +************************************************************ diff --git a/linux-core/drmP.h b/linux-core/drmP.h index 9ad83bde..e47c0892 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -28,6 +28,7 @@ * Rickard E. (Rik) Faith <faith@valinux.com> * */ +/* $XFree86$ */ #ifndef _DRM_P_H_ #define _DRM_P_H_ @@ -44,13 +45,16 @@ #include <linux/pci.h> #include <linux/wrapper.h> #include <linux/version.h> +#include <linux/sched.h> +#include <linux/smp_lock.h> /* For (un)lock_kernel */ +#include <linux/mm.h> #include <asm/io.h> #include <asm/mman.h> #include <asm/uaccess.h> #ifdef CONFIG_MTRR #include <asm/mtrr.h> #endif -#ifdef DRM_AGP +#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) #include <linux/types.h> #include <linux/agp_backend.h> #endif @@ -129,6 +133,19 @@ typedef struct wait_queue *wait_queue_head_t; #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 @@ -312,6 +329,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 { @@ -399,7 +417,7 @@ typedef struct drm_device_dma { wait_queue_head_t waiting; /* Processes waiting on free bufs */ } drm_device_dma_t; -#ifdef DRM_AGP +#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) typedef struct drm_agp_mem { unsigned long handle; agp_memory *memory; @@ -488,9 +506,9 @@ typedef struct drm_device { /* Context support */ int irq; /* Interrupt used by board */ - __volatile__ int context_flag; /* Context swapping flag */ - __volatile__ int interrupt_flag;/* Interruption handler flag */ - __volatile__ int dma_flag; /* DMA dispatch flag */ + __volatile__ long context_flag; /* Context swapping flag */ + __volatile__ long interrupt_flag; /* Interruption handler flag */ + __volatile__ long dma_flag; /* DMA dispatch flag */ struct timer_list timer; /* Timer for delaying ctx switch */ wait_queue_head_t context_wait; /* Processes waiting on ctx switch */ int last_checked; /* Last context checked for DMA */ @@ -513,7 +531,7 @@ typedef struct drm_device { wait_queue_head_t buf_readers; /* Processes waiting to read */ wait_queue_head_t buf_writers; /* Processes waiting to ctx switch */ -#ifdef DRM_AGP +#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) drm_agp_head_t *agp; #endif unsigned long *ctx_bitmap; @@ -548,6 +566,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); @@ -559,6 +580,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); @@ -590,7 +614,7 @@ extern void drm_free_pages(unsigned long address, int order, extern void *drm_ioremap(unsigned long offset, unsigned long size); extern void drm_ioremapfree(void *pt, unsigned long size); -#ifdef DRM_AGP +#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) extern agp_memory *drm_alloc_agp(int pages, u32 type); extern int drm_free_agp(agp_memory *handle, int pages); extern int drm_bind_agp(agp_memory *handle, unsigned int start); @@ -633,7 +657,6 @@ extern void drm_free_buffer(drm_device_t *dev, drm_buf_t *buf); extern void drm_reclaim_buffers(drm_device_t *dev, pid_t pid); extern int drm_context_switch(drm_device_t *dev, int old, int new); extern int drm_context_switch_complete(drm_device_t *dev, int new); -extern void drm_wakeup(drm_device_t *dev, drm_buf_t *buf); extern void drm_clear_next_buffer(drm_device_t *dev); extern int drm_select_queue(drm_device_t *dev, void (*wrapper)(unsigned long)); @@ -714,9 +737,10 @@ extern void drm_ctxbitmap_cleanup(drm_device_t *dev); extern int drm_ctxbitmap_next(drm_device_t *dev); extern void drm_ctxbitmap_free(drm_device_t *dev, int ctx_handle); -#ifdef DRM_AGP +#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) /* AGP/GART support (agpsupport.c) */ extern drm_agp_head_t *drm_agp_init(void); +extern void drm_agp_uninit(void); extern int drm_agp_acquire(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); extern int drm_agp_release(struct inode *inode, struct file *filp, diff --git a/linux-core/i810_dma.c b/linux-core/i810_dma.c index 901be559..1a8290df 100644 --- a/linux-core/i810_dma.c +++ b/linux-core/i810_dma.c @@ -29,11 +29,11 @@ * Keith Whitwell <keithw@valinux.com> * */ +/* $XFree86$ */ #define __NO_VERSION__ #include "drmP.h" #include "i810_drv.h" - #include <linux/interrupt.h> /* For task queue support */ /* in case we don't have a 2.3.99-pre6 kernel or later: */ @@ -156,16 +156,23 @@ static struct file_operations i810_buffer_fops = { int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; - drm_i810_private_t *dev_priv = dev->dev_private; - drm_buf_t *buf = dev_priv->mmap_buffer; - drm_i810_buf_priv_t *buf_priv = buf->dev_private; + drm_file_t *priv = filp->private_data; + drm_device_t *dev; + drm_i810_private_t *dev_priv; + drm_buf_t *buf; + drm_i810_buf_priv_t *buf_priv; + + lock_kernel(); + dev = priv->dev; + dev_priv = dev->dev_private; + buf = dev_priv->mmap_buffer; + buf_priv = buf->dev_private; vma->vm_flags |= (VM_IO | VM_DONTCOPY); vma->vm_file = filp; buf_priv->currently_mapped = I810_BUF_MAPPED; + unlock_kernel(); if (remap_page_range(vma->vm_start, VM_OFFSET(vma), @@ -276,8 +283,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; } @@ -287,9 +294,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; } diff --git a/linux-core/i810_drv.c b/linux-core/i810_drv.c index d7fa9d88..3dc5c6af 100644 --- a/linux-core/i810_drv.c +++ b/linux-core/i810_drv.c @@ -28,19 +28,15 @@ * Jeff Hartmann <jhartmann@valinux.com> * */ +/* $XFree86$ */ #include <linux/config.h> -#define EXPORT_SYMTAB #include "drmP.h" #include "i810_drv.h" - -EXPORT_SYMBOL(i810_init); -EXPORT_SYMBOL(i810_cleanup); - #define I810_NAME "i810" #define I810_DESC "Intel I810" -#define I810_DATE "19991213" +#define I810_DATE "20000719" #define I810_MAJOR 1 #define I810_MINOR 1 #define I810_PATCHLEVEL 0 @@ -49,6 +45,10 @@ static drm_device_t i810_device; drm_ctx_t i810_res_ctx; static struct file_operations i810_fops = { +#if LINUX_VERSION_CODE >= 0x020400 + /* This started being used during 2.4.0-test */ + owner: THIS_MODULE, +#endif open: i810_open, flush: drm_flush, release: i810_release, @@ -119,47 +119,26 @@ static drm_ioctl_desc_t i810_ioctls[] = { #define I810_IOCTL_COUNT DRM_ARRAY_SIZE(i810_ioctls) #ifdef MODULE -int init_module(void); -void cleanup_module(void); static char *i810 = NULL; +#endif -MODULE_AUTHOR("Precision Insight, Inc., Cedar Park, Texas."); +MODULE_AUTHOR("VA Linux Systems, Inc."); MODULE_DESCRIPTION("Intel I810"); MODULE_PARM(i810, "s"); -/* init_module is called when insmod is used to load the module */ - -int init_module(void) -{ - DRM_DEBUG("doing i810_init()\n"); - return i810_init(); -} - -/* cleanup_module is called when rmmod is used to unload the module */ - -void cleanup_module(void) -{ - i810_cleanup(); -} -#endif - #ifndef MODULE -/* i810_setup is called by the kernel to parse command-line options passed - * via the boot-loader (e.g., LILO). It calls the insmod option routine, - * drm_parse_drm. - * - * This is not currently supported, since it requires changes to - * linux/init/main.c. */ - +/* i810_options is called by the kernel to parse command-line options + * passed via the boot-loader (e.g., LILO). It calls the insmod option + * routine, drm_parse_drm. + */ -void __init i810_setup(char *str, int *ints) +static int __init i810_options(char *str) { - if (ints[0] != 0) { - DRM_ERROR("Illegal command line format, ignored\n"); - return; - } drm_parse_options(str); + return 1; } + +__setup("i810=", i810_options); #endif static int i810_setup(drm_device_t *dev) @@ -360,7 +339,7 @@ static int i810_takedown(drm_device_t *dev) /* i810_init is called via init_module at module load time, or via * linux/init/main.c (this is not currently supported). */ -int i810_init(void) +static int i810_init(void) { int retcode; drm_device_t *dev = &i810_device; @@ -419,7 +398,7 @@ int i810_init(void) /* i810_cleanup is called via cleanup_module at module unload time. */ -void i810_cleanup(void) +static void i810_cleanup(void) { drm_device_t *dev = &i810_device; @@ -434,11 +413,16 @@ void i810_cleanup(void) drm_ctxbitmap_cleanup(dev); i810_takedown(dev); if (dev->agp) { + drm_agp_uninit(); drm_free(dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS); dev->agp = NULL; } } +module_init(i810_init); +module_exit(i810_cleanup); + + int i810_version(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { @@ -480,7 +464,9 @@ int i810_open(struct inode *inode, struct file *filp) DRM_DEBUG("open_count = %d\n", dev->open_count); if (!(retcode = drm_open_helper(inode, filp, dev))) { - MOD_INC_USE_COUNT; +#if LINUX_VERSION_CODE < 0x020333 + MOD_INC_USE_COUNT; /* Needed before Linux 2.3.51 */ +#endif atomic_inc(&dev->total_open); spin_lock(&dev->count_lock); if (!dev->open_count++) { @@ -495,9 +481,11 @@ int i810_open(struct inode *inode, struct file *filp) int i810_release(struct inode *inode, struct file *filp) { drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; + drm_device_t *dev; int retcode = 0; + lock_kernel(); + dev = priv->dev; DRM_DEBUG("pid = %d, device = 0x%x, open_count = %d\n", current->pid, dev->device, dev->open_count); @@ -559,7 +547,9 @@ int i810_release(struct inode *inode, struct file *filp) up(&dev->struct_sem); drm_free(priv, sizeof(*priv), DRM_MEM_FILES); - MOD_DEC_USE_COUNT; +#if LINUX_VERSION_CODE < 0x020333 + MOD_DEC_USE_COUNT; /* Needed before Linux 2.3.51 */ +#endif atomic_inc(&dev->total_close); spin_lock(&dev->count_lock); if (!--dev->open_count) { @@ -568,12 +558,15 @@ int i810_release(struct inode *inode, struct file *filp) atomic_read(&dev->ioctl_count), dev->blocked); spin_unlock(&dev->count_lock); + unlock_kernel(); return -EBUSY; } spin_unlock(&dev->count_lock); - return i810_takedown(dev); + unlock_kernel(); + return i810_takedown(dev); } - spin_unlock(&dev->count_lock); + spin_unlock(&dev->count_lock); + unlock_kernel(); return retcode; } diff --git a/linux-core/i810_drv.h b/linux-core/i810_drv.h index f5411c0b..5586a6a6 100644 --- a/linux-core/i810_drv.h +++ b/linux-core/i810_drv.h @@ -28,6 +28,7 @@ * Jeff Hartmann <jhartmann@valinux.com> * */ +/* $XFree86$ */ #ifndef _I810_DRV_H_ #define _I810_DRV_H_ @@ -77,8 +78,6 @@ typedef struct drm_i810_private { } drm_i810_private_t; /* i810_drv.c */ -extern int i810_init(void); -extern void i810_cleanup(void); extern int i810_version(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); extern int i810_open(struct inode *inode, struct file *filp); diff --git a/linux-core/mga_drv.c b/linux-core/mga_drv.c index e77d827b..ab1bc127 100644 --- a/linux-core/mga_drv.c +++ b/linux-core/mga_drv.c @@ -29,17 +29,15 @@ * * */ +/* $XFree86$ */ #include <linux/config.h> -#define EXPORT_SYMTAB #include "drmP.h" #include "mga_drv.h" -EXPORT_SYMBOL(mga_init); -EXPORT_SYMBOL(mga_cleanup); #define MGA_NAME "mga" #define MGA_DESC "Matrox g200/g400" -#define MGA_DATE "19991213" +#define MGA_DATE "20000719" #define MGA_MAJOR 1 #define MGA_MINOR 0 #define MGA_PATCHLEVEL 0 @@ -48,6 +46,10 @@ static drm_device_t mga_device; drm_ctx_t mga_res_ctx; static struct file_operations mga_fops = { +#if LINUX_VERSION_CODE >= 0x020400 + /* This started being used during 2.4.0-test */ + owner: THIS_MODULE, +#endif open: mga_open, flush: drm_flush, release: mga_release, @@ -118,47 +120,26 @@ static drm_ioctl_desc_t mga_ioctls[] = { #define MGA_IOCTL_COUNT DRM_ARRAY_SIZE(mga_ioctls) #ifdef MODULE -int init_module(void); -void cleanup_module(void); static char *mga = NULL; +#endif -MODULE_AUTHOR("Precision Insight, Inc., Cedar Park, Texas."); +MODULE_AUTHOR("VA Linux Systems, Inc."); MODULE_DESCRIPTION("Matrox g200/g400"); MODULE_PARM(mga, "s"); -/* init_module is called when insmod is used to load the module */ - -int init_module(void) -{ - DRM_DEBUG("doing mga_init()\n"); - return mga_init(); -} - -/* cleanup_module is called when rmmod is used to unload the module */ - -void cleanup_module(void) -{ - mga_cleanup(); -} -#endif - #ifndef MODULE -/* mga_setup is called by the kernel to parse command-line options passed +/* mga_options is called by the kernel to parse command-line options passed * via the boot-loader (e.g., LILO). It calls the insmod option routine, * drm_parse_drm. - * - * This is not currently supported, since it requires changes to - * linux/init/main.c. */ - + */ -void __init mga_setup(char *str, int *ints) +static int __init mga_options(char *str) { - if (ints[0] != 0) { - DRM_ERROR("Illegal command line format, ignored\n"); - return; - } drm_parse_options(str); + return 1; } + +__setup("mga=", mga_options); #endif static int mga_setup(drm_device_t *dev) @@ -357,7 +338,7 @@ static int mga_takedown(drm_device_t *dev) /* mga_init is called via init_module at module load time, or via * linux/init/main.c (this is not currently supported). */ -int mga_init(void) +static int mga_init(void) { int retcode; drm_device_t *dev = &mga_device; @@ -422,7 +403,7 @@ int mga_init(void) /* mga_cleanup is called via cleanup_module at module unload time. */ -void mga_cleanup(void) +static void mga_cleanup(void) { drm_device_t *dev = &mga_device; @@ -448,11 +429,16 @@ void mga_cleanup(void) mga_takedown(dev); if (dev->agp) { + drm_agp_uninit(); drm_free(dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS); dev->agp = NULL; } } +module_init(mga_init); +module_exit(mga_cleanup); + + int mga_version(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { @@ -494,7 +480,9 @@ int mga_open(struct inode *inode, struct file *filp) DRM_DEBUG("open_count = %d\n", dev->open_count); if (!(retcode = drm_open_helper(inode, filp, dev))) { - MOD_INC_USE_COUNT; +#if LINUX_VERSION_CODE < 0x020333 + MOD_INC_USE_COUNT; /* Needed before Linux 2.3.51 */ +#endif atomic_inc(&dev->total_open); spin_lock(&dev->count_lock); if (!dev->open_count++) { @@ -509,9 +497,11 @@ int mga_open(struct inode *inode, struct file *filp) int mga_release(struct inode *inode, struct file *filp) { drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; + drm_device_t *dev; int retcode = 0; + lock_kernel(); + dev = priv->dev; DRM_DEBUG("pid = %d, device = 0x%x, open_count = %d\n", current->pid, dev->device, dev->open_count); @@ -573,7 +563,9 @@ int mga_release(struct inode *inode, struct file *filp) up(&dev->struct_sem); drm_free(priv, sizeof(*priv), DRM_MEM_FILES); - MOD_DEC_USE_COUNT; +#if LINUX_VERSION_CODE < 0x020333 + MOD_DEC_USE_COUNT; /* Needed before Linux 2.3.51 */ +#endif atomic_inc(&dev->total_close); spin_lock(&dev->count_lock); if (!--dev->open_count) { @@ -582,12 +574,15 @@ int mga_release(struct inode *inode, struct file *filp) atomic_read(&dev->ioctl_count), dev->blocked); spin_unlock(&dev->count_lock); + unlock_kernel(); return -EBUSY; } spin_unlock(&dev->count_lock); + unlock_kernel(); return mga_takedown(dev); } - spin_unlock(&dev->count_lock); + spin_unlock(&dev->count_lock); + unlock_kernel(); return retcode; } diff --git a/linux-core/r128_drv.c b/linux-core/r128_drv.c index 8b669888..9d768ce1 100644 --- a/linux-core/r128_drv.c +++ b/linux-core/r128_drv.c @@ -28,17 +28,15 @@ * Kevin E. Martin <martin@valinux.com> * */ +/* $XFree86$ */ #include <linux/config.h> -#define EXPORT_SYMTAB #include "drmP.h" #include "r128_drv.h" -EXPORT_SYMBOL(r128_init); -EXPORT_SYMBOL(r128_cleanup); #define R128_NAME "r128" -#define R128_DESC "r128" -#define R128_DATE "20000607" +#define R128_DESC "ATI Rage 128" +#define R128_DATE "20000719" #define R128_MAJOR 1 #define R128_MINOR 0 #define R128_PATCHLEVEL 0 @@ -47,6 +45,10 @@ static drm_device_t r128_device; drm_ctx_t r128_res_ctx; static struct file_operations r128_fops = { +#if LINUX_VERSION_CODE >= 0x020400 + /* This started being used during 2.4.0-test */ + owner: THIS_MODULE, +#endif open: r128_open, flush: drm_flush, release: r128_release, @@ -93,7 +95,7 @@ static drm_ioctl_desc_t r128_ioctls[] = { [DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = { r128_unlock, 1, 0 }, [DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = { drm_finish, 1, 0 }, -#ifdef DRM_AGP +#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) [DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = { drm_agp_acquire, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = { drm_agp_release, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = { drm_agp_enable, 1, 1 }, @@ -114,46 +116,26 @@ static drm_ioctl_desc_t r128_ioctls[] = { #define R128_IOCTL_COUNT DRM_ARRAY_SIZE(r128_ioctls) #ifdef MODULE -int init_module(void); -void cleanup_module(void); static char *r128 = NULL; +#endif -MODULE_AUTHOR("Precision Insight, Inc., Cedar Park, Texas."); +MODULE_AUTHOR("VA Linux Systems, Inc."); MODULE_DESCRIPTION("r128"); MODULE_PARM(r128, "s"); -/* init_module is called when insmod is used to load the module */ - -int init_module(void) -{ - return r128_init(); -} - -/* cleanup_module is called when rmmod is used to unload the module */ - -void cleanup_module(void) -{ - r128_cleanup(); -} -#endif - #ifndef MODULE -/* r128_setup is called by the kernel to parse command-line options passed - * via the boot-loader (e.g., LILO). It calls the insmod option routine, - * drm_parse_drm. - * - * This is not currently supported, since it requires changes to - * linux/init/main.c. */ - +/* r128_options is called by the kernel to parse command-line options + * passed via the boot-loader (e.g., LILO). It calls the insmod option + * routine, drm_parse_drm. + */ -void __init r128_setup(char *str, int *ints) +static int __init r128_options(char *str) { - if (ints[0] != 0) { - DRM_ERROR("Illegal command line format, ignored\n"); - return; - } drm_parse_options(str); + return 1; } + +__setup("r128=", r128_options); #endif static int r128_setup(drm_device_t *dev) @@ -255,7 +237,7 @@ static int r128_takedown(drm_device_t *dev) dev->magiclist[i].head = dev->magiclist[i].tail = NULL; } -#ifdef DRM_AGP +#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) /* Clear AGP information */ if (dev->agp) { drm_agp_mem_t *entry; @@ -342,7 +324,7 @@ static int r128_takedown(drm_device_t *dev) /* r128_init is called via init_module at module load time, or via * linux/init/main.c (this is not currently supported). */ -int r128_init(void) +static int r128_init(void) { int retcode; drm_device_t *dev = &r128_device; @@ -367,8 +349,15 @@ int r128_init(void) drm_mem_init(); drm_proc_init(dev); -#ifdef DRM_AGP +#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) dev->agp = drm_agp_init(); + if (dev->agp == NULL) { + DRM_ERROR("Cannot initialize agpgart module.\n"); + drm_proc_cleanup(); + misc_deregister(&r128_misc); + r128_takedown(dev); + return -ENOMEM; + } #ifdef CONFIG_MTRR dev->agp->agp_mtrr = mtrr_add(dev->agp->agp_info.aper_base, @@ -399,7 +388,7 @@ int r128_init(void) /* r128_cleanup is called via cleanup_module at module unload time. */ -void r128_cleanup(void) +static void r128_cleanup(void) { drm_device_t *dev = &r128_device; @@ -413,15 +402,19 @@ void r128_cleanup(void) } drm_ctxbitmap_cleanup(dev); r128_takedown(dev); -#ifdef DRM_AGP +#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) if (dev->agp) { - /* FIXME -- free other information, too */ + drm_agp_uninit(); drm_free(dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS); dev->agp = NULL; } #endif } +module_init(r128_init); +module_exit(r128_cleanup); + + int r128_version(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { @@ -463,7 +456,9 @@ int r128_open(struct inode *inode, struct file *filp) DRM_DEBUG("open_count = %d\n", dev->open_count); if (!(retcode = drm_open_helper(inode, filp, dev))) { - MOD_INC_USE_COUNT; +#if LINUX_VERSION_CODE < 0x020333 + MOD_INC_USE_COUNT; /* Needed before Linux 2.3.51 */ +#endif atomic_inc(&dev->total_open); spin_lock(&dev->count_lock); if (!dev->open_count++) { @@ -472,18 +467,23 @@ int r128_open(struct inode *inode, struct file *filp) } spin_unlock(&dev->count_lock); } + return retcode; } int r128_release(struct inode *inode, struct file *filp) { drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; + drm_device_t *dev; int retcode = 0; + lock_kernel(); + dev = priv->dev; DRM_DEBUG("open_count = %d\n", dev->open_count); if (!(retcode = drm_release(inode, filp))) { - MOD_DEC_USE_COUNT; +#if LINUX_VERSION_CODE < 0x020333 + MOD_DEC_USE_COUNT; /* Needed before Linux 2.3.51 */ +#endif atomic_inc(&dev->total_close); spin_lock(&dev->count_lock); if (!--dev->open_count) { @@ -492,13 +492,17 @@ int r128_release(struct inode *inode, struct file *filp) atomic_read(&dev->ioctl_count), dev->blocked); spin_unlock(&dev->count_lock); + unlock_kernel(); return -EBUSY; } spin_unlock(&dev->count_lock); + unlock_kernel(); return r128_takedown(dev); } spin_unlock(&dev->count_lock); } + + unlock_kernel(); return retcode; } @@ -664,19 +668,11 @@ int r128_lock(struct inode *inode, struct file *filp, unsigned int cmd, } } -#if 0 - DRM_ERROR("pid = %5d, old counter = %5ld\n", - current->pid, current->counter); -#endif +#if LINUX_VERSION_CODE < 0x020400 if (lock.context != r128_res_ctx.handle) { current->counter = 5; current->priority = DEF_PRIORITY/4; } -#if 0 - while (current->counter > 25) - current->counter >>= 1; /* decrease time slice */ - DRM_ERROR("pid = %5d, new counter = %5ld\n", - current->pid, current->counter); #endif DRM_DEBUG("%d %s\n", lock.context, ret ? "interrupted" : "has lock"); @@ -718,19 +714,11 @@ int r128_unlock(struct inode *inode, struct file *filp, unsigned int cmd, } } -#if 0 - current->policy |= SCHED_YIELD; - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(1000); -#endif - +#if LINUX_VERSION_CODE < 0x020400 if (lock.context != r128_res_ctx.handle) { current->counter = 5; current->priority = DEF_PRIORITY; } -#if 0 - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(10); #endif return 0; diff --git a/linux-core/sis_drv.c b/linux-core/sis_drv.c index 1e8abb7f..9acfc1e4 100644 --- a/linux-core/sis_drv.c +++ b/linux-core/sis_drv.c @@ -1,7 +1,8 @@ -/* sis.c -- sis driver -*- linux-c -*- +/* sis_drv.c -- sis driver -*- linux-c -*- * Created: Thu Oct 7 10:38:32 1999 by faith@precisioninsight.com * - * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas. + * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. + * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -22,13 +23,14 @@ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. - * + * * Authors: - * Rickard E. (Rik) Faith <faith@precisioninsight.com> - * Daryll Strauss <daryll@precisioninsight.com> + * Rickard E. (Rik) Faith <faith@valinux.com> + * Daryll Strauss <daryll@valinux.com> + * Sung-Ching Lin <sclin@sis.com.tw> * */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/sis_drv.c,v 1.2 2000/08/04 03:51:47 tsi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/sis_drv.c,v 1.6 2000/08/28 02:43:16 tsi Exp $ */ #include <linux/config.h> #include "drmP.h" @@ -36,16 +38,20 @@ #include "sis_drv.h" #define SIS_NAME "sis" -#define SIS_DESC "sis" -#define SIS_DATE "19991009" -#define SIS_MAJOR 0 +#define SIS_DESC "SIS 300/630/540" +#define SIS_DATE "20000831" +#define SIS_MAJOR 1 #define SIS_MINOR 0 -#define SIS_PATCHLEVEL 1 +#define SIS_PATCHLEVEL 0 static drm_device_t sis_device; drm_ctx_t sis_res_ctx; static struct file_operations sis_fops = { +#if LINUX_VERSION_CODE >= 0x020400 + /* This started being used during 2.4.0-test */ + owner: THIS_MODULE, +#endif open: sis_open, flush: drm_flush, release: sis_release, @@ -71,14 +77,14 @@ static drm_ioctl_desc_t sis_ioctls[] = { [DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)] = { drm_setunique, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_BLOCK)] = { drm_block, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] = { drm_unblock, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = { drm_authmagic, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = { drm_addmap, 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = { sis_addctx, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = { sis_rmctx, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = { sis_modctx, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] = { sis_getctx, 1, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = { sis_switchctx, 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = { sis_switchctx, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)] = { sis_newctx, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)] = { sis_resctx, 1, 0 }, [DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)] = { drm_adddraw, 1, 1 }, @@ -86,18 +92,16 @@ static drm_ioctl_desc_t sis_ioctls[] = { [DRM_IOCTL_NR(DRM_IOCTL_LOCK)] = { sis_lock, 1, 0 }, [DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = { sis_unlock, 1, 0 }, [DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = { drm_finish, 1, 0 }, - -#ifdef DRM_AGP - [DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = { drm_agp_acquire, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = { drm_agp_release, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = { drm_agp_enable, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)] = { drm_agp_info, 1, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)] = { drm_agp_alloc, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = { drm_agp_free, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = { drm_agp_bind, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = { drm_agp_unbind, 1, 1 }, +#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) + [DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = {drm_agp_acquire, 1, 1}, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = {drm_agp_release, 1, 1}, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = {drm_agp_enable, 1, 1}, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)] = {drm_agp_info, 1, 1}, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)] = {drm_agp_alloc, 1, 1}, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = {drm_agp_free, 1, 1}, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = {drm_agp_bind, 1, 1}, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = {drm_agp_unbind, 1, 1}, #endif - /* FB Memory Management */ [DRM_IOCTL_NR(SIS_IOCTL_FB_ALLOC)] = { sis_fb_alloc, 1, 1 }, [DRM_IOCTL_NR(SIS_IOCTL_FB_FREE)] = { sis_fb_free, 1, 1 }, @@ -120,10 +124,25 @@ static drm_ioctl_desc_t sis_ioctls[] = { static char *sis = NULL; #endif -MODULE_AUTHOR("Precision Insight, Inc., Cedar Park, Texas."); +MODULE_AUTHOR("VA Linux Systems, Inc."); MODULE_DESCRIPTION("sis"); MODULE_PARM(sis, "s"); +#ifndef MODULE +/* sis_options is called by the kernel to parse command-line options + * passed via the boot-loader (e.g., LILO). It calls the insmod option + * routine, drm_parse_drm. + */ + +static int __init sis_options(char *str) +{ + drm_parse_options(str); + return 1; +} + +__setup("sis=", sis_options); +#endif + static int sis_setup(drm_device_t *dev) { int i; @@ -225,30 +244,22 @@ static int sis_takedown(drm_device_t *dev) } dev->magiclist[i].head = dev->magiclist[i].tail = NULL; } -#ifdef DRM_AGP - /* Clear AGP information */ +#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) + /* Clear AGP information */ if (dev->agp) { - drm_agp_mem_t *entry; - drm_agp_mem_t *nexte; - - /* Remove AGP resources, but leave dev->agp - intact until cleanup is called. */ - for (entry = dev->agp->memory; entry; entry = nexte) { - nexte = entry->next; - if (entry->bound) drm_unbind_agp(entry->memory); - drm_free_agp(entry->memory, entry->pages); - drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS); + drm_agp_mem_t *temp; + drm_agp_mem_t *temp_next; + + temp = dev->agp->memory; + while(temp != NULL) { + temp_next = temp->next; + drm_free_agp(temp->memory, temp->pages); + drm_free(temp, sizeof(*temp), DRM_MEM_AGPLISTS); + temp = temp_next; } - dev->agp->memory = NULL; - - if (dev->agp->acquired && drm_agp.release) - (*drm_agp.release)(); - - dev->agp->acquired = 0; - dev->agp->enabled = 0; - } + if (dev->agp->acquired) (*drm_agp.release)(); + } #endif - /* Clear vma list (only built for debugging) */ if (dev->vmalist) { for (vma = dev->vmalist; vma; vma = vma_next) { @@ -309,7 +320,7 @@ static int sis_takedown(drm_device_t *dev) /* sis_init is called via init_module at module load time, or via * linux/init/main.c (this is not currently supported). */ -int sis_init(void) +static int sis_init(void) { int retcode; drm_device_t *dev = &sis_device; @@ -333,27 +344,16 @@ int sis_init(void) drm_mem_init(); drm_proc_init(dev); - -#ifdef DRM_AGP - DRM_DEBUG("doing agp init\n"); +#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) dev->agp = drm_agp_init(); - if(dev->agp == NULL) { - /* TODO, if no agp, run MMIO mode */ - DRM_INFO("The sis drm module requires the agpgart module" - " to function correctly\nPlease load the agpgart" - " module before you load the mga module\n"); - drm_proc_cleanup(); - misc_deregister(&sis_misc); - sis_takedown(dev); - return -ENOMEM; - } -#ifdef CONFIG_MTRR - dev->agp->agp_mtrr = mtrr_add(dev->agp->agp_info.aper_base, - dev->agp->agp_info.aper_size * 1024 * 1024, - MTRR_TYPE_WRCOMB, - 1); -#endif #endif + if((retcode = drm_ctxbitmap_init(dev))) { + DRM_ERROR("Cannot allocate memory for context bitmap.\n"); + drm_proc_cleanup(); + misc_deregister(&sis_misc); + sis_takedown(dev); + return retcode; + } DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", SIS_NAME, @@ -368,7 +368,7 @@ int sis_init(void) /* sis_cleanup is called via cleanup_module at module unload time. */ -void sis_cleanup(void) +static void sis_cleanup(void) { drm_device_t *dev = &sis_device; @@ -380,27 +380,21 @@ void sis_cleanup(void) } else { DRM_INFO("Module unloaded\n"); } -#ifdef DRM_AGP -#ifdef CONFIG_MTRR - if(dev->agp && dev->agp->agp_mtrr) { - int retval; - retval = mtrr_del(dev->agp->agp_mtrr, - dev->agp->agp_info.aper_base, - dev->agp->agp_info.aper_size * 1024*1024); - DRM_DEBUG("mtrr_del = %d\n", retval); - } -#endif -#endif - + drm_ctxbitmap_cleanup(dev); sis_takedown(dev); -#ifdef DRM_AGP +#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) if (dev->agp) { + drm_agp_uninit(); drm_free(dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS); dev->agp = NULL; } #endif } +module_init(sis_init); +module_exit(sis_cleanup); + + int sis_version(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { @@ -439,11 +433,12 @@ int sis_open(struct inode *inode, struct file *filp) { drm_device_t *dev = &sis_device; int retcode = 0; - + DRM_DEBUG("open_count = %d\n", dev->open_count); - if (!(retcode = drm_open_helper(inode, filp, dev))) { - MOD_INC_USE_COUNT; +#if LINUX_VERSION_CODE < 0x020333 + MOD_INC_USE_COUNT; /* Needed before Linux 2.3.51 */ +#endif atomic_inc(&dev->total_open); spin_lock(&dev->count_lock); if (!dev->open_count++) { @@ -458,13 +453,17 @@ int sis_open(struct inode *inode, struct file *filp) int sis_release(struct inode *inode, struct file *filp) { drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; + drm_device_t *dev; int retcode = 0; - DRM_DEBUG("open_count = %d\n", dev->open_count); + lock_kernel(); + dev = priv->dev; + DRM_DEBUG("open_count = %d\n", dev->open_count); if (!(retcode = drm_release(inode, filp))) { - MOD_DEC_USE_COUNT; +#if LINUX_VERSION_CODE < 0x020333 + MOD_DEC_USE_COUNT; /* Needed before Linux 2.3.51 */ +#endif atomic_inc(&dev->total_close); spin_lock(&dev->count_lock); if (!--dev->open_count) { @@ -473,13 +472,17 @@ int sis_release(struct inode *inode, struct file *filp) atomic_read(&dev->ioctl_count), dev->blocked); spin_unlock(&dev->count_lock); + unlock_kernel(); return -EBUSY; } spin_unlock(&dev->count_lock); + unlock_kernel(); return sis_takedown(dev); } spin_unlock(&dev->count_lock); } + + unlock_kernel(); return retcode; } @@ -594,7 +597,9 @@ int sis_lock(struct inode *inode, struct file *filp, unsigned int cmd, /* Contention */ atomic_inc(&dev->total_sleeps); current->state = TASK_INTERRUPTIBLE; +#if 1 current->policy |= SCHED_YIELD; +#endif schedule(); if (signal_pending(current)) { ret = -ERESTARTSYS; @@ -643,11 +648,12 @@ int sis_lock(struct inode *inode, struct file *filp, unsigned int cmd, } } +#if LINUX_VERSION_CODE < 0x020400 if (lock.context != sis_res_ctx.handle) { current->counter = 5; current->priority = DEF_PRIORITY/4; } - +#endif DRM_DEBUG("%d %s\n", lock.context, ret ? "interrupted" : "has lock"); #if DRM_DMA_HISTOGRAM @@ -687,29 +693,13 @@ int sis_unlock(struct inode *inode, struct file *filp, unsigned int cmd, DRM_ERROR("\n"); } } - + +#if LINUX_VERSION_CODE < 0x020400 if (lock.context != sis_res_ctx.handle) { current->counter = 5; current->priority = DEF_PRIORITY; } - +#endif + return 0; } - -module_init(sis_init); -module_exit(sis_cleanup); - -#ifndef MODULE -/* - * sis_setup is called by the kernel to parse command-line options passed - * via the boot-loader (e.g., LILO). It calls the insmod option routine, - * drm_parse_options. - */ -static int __init sis_options(char *str) -{ - drm_parse_options(str); - return 1; -} - -__setup("sis=", sis_options); -#endif diff --git a/linux-core/tdfx_drv.c b/linux-core/tdfx_drv.c index 582832b5..9cc3c993 100644 --- a/linux-core/tdfx_drv.c +++ b/linux-core/tdfx_drv.c @@ -29,17 +29,15 @@ * Daryll Strauss <daryll@valinux.com> * */ +/* $XFree86$ */ #include <linux/config.h> -#define EXPORT_SYMTAB #include "drmP.h" #include "tdfx_drv.h" -EXPORT_SYMBOL(tdfx_init); -EXPORT_SYMBOL(tdfx_cleanup); #define TDFX_NAME "tdfx" -#define TDFX_DESC "tdfx" -#define TDFX_DATE "19991009" +#define TDFX_DESC "3dfx Banshee/Voodoo3+" +#define TDFX_DATE "20000719" #define TDFX_MAJOR 1 #define TDFX_MINOR 0 #define TDFX_PATCHLEVEL 0 @@ -48,6 +46,10 @@ static drm_device_t tdfx_device; drm_ctx_t tdfx_res_ctx; static struct file_operations tdfx_fops = { +#if LINUX_VERSION_CODE >= 0x020400 + /* This started being used during 2.4.0-test */ + owner: THIS_MODULE, +#endif open: tdfx_open, flush: drm_flush, release: tdfx_release, @@ -88,7 +90,7 @@ static drm_ioctl_desc_t tdfx_ioctls[] = { [DRM_IOCTL_NR(DRM_IOCTL_LOCK)] = { tdfx_lock, 1, 0 }, [DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = { tdfx_unlock, 1, 0 }, [DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = { drm_finish, 1, 0 }, -#ifdef DRM_AGP +#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) [DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = {drm_agp_acquire, 1, 1}, [DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = {drm_agp_release, 1, 1}, [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = {drm_agp_enable, 1, 1}, @@ -102,46 +104,26 @@ static drm_ioctl_desc_t tdfx_ioctls[] = { #define TDFX_IOCTL_COUNT DRM_ARRAY_SIZE(tdfx_ioctls) #ifdef MODULE -int init_module(void); -void cleanup_module(void); static char *tdfx = NULL; +#endif -MODULE_AUTHOR("Precision Insight, Inc., Cedar Park, Texas."); +MODULE_AUTHOR("VA Linux Systems, Inc."); MODULE_DESCRIPTION("tdfx"); MODULE_PARM(tdfx, "s"); -/* init_module is called when insmod is used to load the module */ - -int init_module(void) -{ - return tdfx_init(); -} - -/* cleanup_module is called when rmmod is used to unload the module */ - -void cleanup_module(void) -{ - tdfx_cleanup(); -} -#endif - #ifndef MODULE -/* tdfx_setup is called by the kernel to parse command-line options passed - * via the boot-loader (e.g., LILO). It calls the insmod option routine, - * drm_parse_drm. - * - * This is not currently supported, since it requires changes to - * linux/init/main.c. */ - +/* tdfx_options is called by the kernel to parse command-line options + * passed via the boot-loader (e.g., LILO). It calls the insmod option + * routine, drm_parse_drm. + */ -void __init tdfx_setup(char *str, int *ints) +static int __init tdfx_options(char *str) { - if (ints[0] != 0) { - DRM_ERROR("Illegal command line format, ignored\n"); - return; - } drm_parse_options(str); + return 1; } + +__setup("tdfx=", tdfx_options); #endif static int tdfx_setup(drm_device_t *dev) @@ -241,7 +223,7 @@ static int tdfx_takedown(drm_device_t *dev) } dev->magiclist[i].head = dev->magiclist[i].tail = NULL; } -#ifdef DRM_AGP +#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) /* Clear AGP information */ if (dev->agp) { drm_agp_mem_t *temp; @@ -254,9 +236,7 @@ static int tdfx_takedown(drm_device_t *dev) drm_free(temp, sizeof(*temp), DRM_MEM_AGPLISTS); temp = temp_next; } - if(dev->agp->acquired) (*drm_agp.release)(); - drm_free(dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS); - dev->agp = NULL; + if (dev->agp->acquired) (*drm_agp.release)(); } #endif /* Clear vma list (only built for debugging) */ @@ -319,7 +299,7 @@ static int tdfx_takedown(drm_device_t *dev) /* tdfx_init is called via init_module at module load time, or via * linux/init/main.c (this is not currently supported). */ -int tdfx_init(void) +static int tdfx_init(void) { int retcode; drm_device_t *dev = &tdfx_device; @@ -343,7 +323,7 @@ int tdfx_init(void) drm_mem_init(); drm_proc_init(dev); -#ifdef DRM_AGP +#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) dev->agp = drm_agp_init(); #endif if((retcode = drm_ctxbitmap_init(dev))) { @@ -367,7 +347,7 @@ int tdfx_init(void) /* tdfx_cleanup is called via cleanup_module at module unload time. */ -void tdfx_cleanup(void) +static void tdfx_cleanup(void) { drm_device_t *dev = &tdfx_device; @@ -381,8 +361,19 @@ void tdfx_cleanup(void) } drm_ctxbitmap_cleanup(dev); tdfx_takedown(dev); +#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) + if (dev->agp) { + drm_agp_uninit(); + drm_free(dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS); + dev->agp = NULL; + } +#endif } +module_init(tdfx_init); +module_exit(tdfx_cleanup); + + int tdfx_version(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { @@ -424,7 +415,9 @@ int tdfx_open(struct inode *inode, struct file *filp) DRM_DEBUG("open_count = %d\n", dev->open_count); if (!(retcode = drm_open_helper(inode, filp, dev))) { - MOD_INC_USE_COUNT; +#if LINUX_VERSION_CODE < 0x020333 + MOD_INC_USE_COUNT; /* Needed before Linux 2.3.51 */ +#endif atomic_inc(&dev->total_open); spin_lock(&dev->count_lock); if (!dev->open_count++) { @@ -439,12 +432,17 @@ int tdfx_open(struct inode *inode, struct file *filp) int tdfx_release(struct inode *inode, struct file *filp) { drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; + drm_device_t *dev; int retcode = 0; + lock_kernel(); + dev = priv->dev; + DRM_DEBUG("open_count = %d\n", dev->open_count); if (!(retcode = drm_release(inode, filp))) { - MOD_DEC_USE_COUNT; +#if LINUX_VERSION_CODE < 0x020333 + MOD_DEC_USE_COUNT; /* Needed before Linux 2.3.51 */ +#endif atomic_inc(&dev->total_close); spin_lock(&dev->count_lock); if (!--dev->open_count) { @@ -453,13 +451,17 @@ int tdfx_release(struct inode *inode, struct file *filp) atomic_read(&dev->ioctl_count), dev->blocked); spin_unlock(&dev->count_lock); + unlock_kernel(); return -EBUSY; } spin_unlock(&dev->count_lock); + unlock_kernel(); return tdfx_takedown(dev); } spin_unlock(&dev->count_lock); } + + unlock_kernel(); return retcode; } @@ -625,19 +627,11 @@ int tdfx_lock(struct inode *inode, struct file *filp, unsigned int cmd, } } -#if 0 - DRM_ERROR("pid = %5d, old counter = %5ld\n", - current->pid, current->counter); -#endif +#if LINUX_VERSION_CODE < 0x020400 if (lock.context != tdfx_res_ctx.handle) { current->counter = 5; current->priority = DEF_PRIORITY/4; } -#if 0 - while (current->counter > 25) - current->counter >>= 1; /* decrease time slice */ - DRM_ERROR("pid = %5d, new counter = %5ld\n", - current->pid, current->counter); #endif DRM_DEBUG("%d %s\n", lock.context, ret ? "interrupted" : "has lock"); @@ -679,19 +673,11 @@ int tdfx_unlock(struct inode *inode, struct file *filp, unsigned int cmd, } } -#if 0 - current->policy |= SCHED_YIELD; - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(1000); -#endif - +#if LINUX_VERSION_CODE < 0x020400 if (lock.context != tdfx_res_ctx.handle) { current->counter = 5; current->priority = DEF_PRIORITY; } -#if 0 - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(10); #endif return 0; diff --git a/linux/Makefile.kernel b/linux/Makefile.kernel index e262213a..9f8b702d 100644 --- a/linux/Makefile.kernel +++ b/linux/Makefile.kernel @@ -1,53 +1,89 @@ +# $XFree86$ # # Makefile for the drm device driver. This driver provides support for # the Direct Rendering Infrastructure (DRI) in XFree86 4.x. # -# Note! Dependencies are done automagically by 'make dep', which also -# removes any old dependencies. DON'T put your own dependencies here -# unless it's something special (ie not a .c file). + +# drm.o is a fake target -- it is never built +# The real targets are in the module-list +O_TARGET := drm.o +module-list := gamma.o tdfx.o r128.o ffb.o mga.o i810.o +export-objs := $(patsubst %.o,%_drv.o,$(module-list)) + +# libs-objs are included in every module so that radical changes to the +# architecture of the DRM support library can be made at a later time. +# +# The downside is that each module is larger, and a system that uses +# more than one module (i.e., a dual-head system) will use more memory +# (but a system that uses exactly one module will use the same amount of +# memory). # -# Note 2! The CFLAGS definitions are now inherited from the -# parent makes.. +# The upside is that if the DRM support library ever becomes insufficient +# for new families of cards, a new library can be implemented for those new +# cards without impacting the drivers for the old cards. This is significant, +# because testing architectural changes to old cards may be impossible, and +# may delay the implementation of a better architecture. We've traded slight +# memory waste (in the dual-head case) for greatly improved long-term +# maintainability. # -# $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/Makefile.kernel,v 1.6 2000/06/17 00:03:34 martin Exp $ +lib-objs := init.o memory.o proc.o auth.o context.o drawable.o bufs.o +lib-objs += lists.o lock.o ioctl.o fops.o vm.o dma.o ctxbitmap.o -L_TARGET := libdrm.a +ifeq ($(CONFIG_AGP),y) + lib-objs += agpsupport.o +else + ifeq ($(CONFIG_AGP),m) + lib-objs += agpsupport.o + endif +endif -L_OBJS := init.o memory.o proc.o auth.o context.o drawable.o bufs.o \ - lists.o lock.o ioctl.o fops.o vm.o dma.o ctxbitmap.o \ - agpsupport.o +gamma-objs := $(lib-objs) gamma_drv.o gamma_dma.o +tdfx-objs := $(lib-objs) tdfx_drv.o tdfx_context.o +r128-objs := $(lib-objs) r128_drv.o r128_dma.o r128_context.o r128_bufs.o +ffb-objs := $(lib-objs) ffb_drv.o ffb_context.o +mga-objs := $(lib-objs) mga_drv.o mga_dma.o mga_context.o mga_bufs.o \ + mga_state.o +i810-objs := $(lib-objs) i810_drv.o i810_dma.o i810_context.o i810_bufs.o -M_OBJS := +obj-$(CONFIG_DRM_GAMMA) += gamma.o $(gamma-objs) +obj-$(CONFIG_DRM_TDFX) += tdfx.o $(tdfx-objs) +obj-$(CONFIG_DRM_R128) += r128.o $(r128-objs) +obj-$(CONFIG_DRM_FFB) += ffb.o $(ffb-objs) -ifdef CONFIG_DRM_GAMMA -M_OBJS += gamma.o +ifneq ($CONFIG_AGP),) +obj-$(CONFIG_DRM_MGA) += mga.o $(mga-objs) +obj-$(CONFIG_DRM_I810) += i810.o $(i810-objs) endif -ifdef CONFIG_DRM_TDFX -M_OBJS += tdfx.o -endif +# Take module names out of obj-y and int-m -ifdef CONFIG_DRM_MGA -M_OBJS += mga.o -endif +obj-y := $(filter-out $(module-list), $(obj-y)) +int-m := $(filter-out $(module-list), $(obj-m)) -ifdef CONFIG_DRM_R128 -M_OBJS += r128.o -endif +# Translate to Rules.make lists. + +O_OBJS := $(filter-out $(export-objs), $(obj-y)) +OX_OBJS := $(filter $(export-objs), $(obj-y)) +M_OBJS := $(sort $(filter $(module-list), $(obj-m))) +MI_OBJS := $(sort $(filter-out $(export-objs), $(int-m))) +MIX_OBJS := $(sort $(filter $(export-objs), $(int-m))) include $(TOPDIR)/Rules.make -gamma.o: gamma_drv.o gamma_dma.o $(L_TARGET) - $(LD) $(LD_RFLAG) -r -o $@ gamma_drv.o gamma_dma.o -L. -ldrm +gamma.o: $(gamma-objs) + $(LD) -r -o $@ $(gamma-objs) + +tdfx.o: $(tdfx-objs) + $(LD) -r -o $@ $(tdfx-objs) -tdfx.o: tdfx_drv.o tdfx_context.o $(L_TARGET) - $(LD) $(LD_RFLAG) -r -o $@ tdfx_drv.o tdfx_context.o -L. -ldrm +mga.o: $(mga-objs) + $(LD) -r -o $@ $(mga-objs) -i810.o: i810_drv.o i810_context.o $(L_TARGET) - $(LD) $(LD_RFLAG) -r -o $@ i810_drv.o i810_bufs.o i810_dma.o i810_context.o -L. -ldrm +i810.o: $(i810-objs) + $(LD) -r -o $@ $(i810-objs) -mga.o: mga_drv.o mga_context.o mga_dma.o mga_bufs.o $(L_TARGET) - $(LD) $(LD_RFLAG) -r -o $@ mga_drv.o mga_bufs.o mga_dma.o mga_context.o mga_state.o -L. -ldrm +r128.o: $(r128-objs) + $(LD) -r -o $@ $(r128-objs) -r128.o: r128_drv.o r128_context.o $(L_TARGET) - $(LD) $(LD_RFLAG) -r -o $@ r128_drv.o r128_context.o -L. -ldrm +ffb.o: $(ffb-objs) + $(LD) -r -o $@ $(ffb-objs) diff --git a/linux/Makefile.linux b/linux/Makefile.linux index 9e93331a..afdde702 100644 --- a/linux/Makefile.linux +++ b/linux/Makefile.linux @@ -24,7 +24,7 @@ # ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # DEALINGS IN THE SOFTWARE. # -# $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/Makefile.linux,v 1.9 2000/08/04 03:51:47 tsi Exp $ +# $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/Makefile.linux,v 1.10 2000/08/25 13:42:39 dawes Exp $ # # ***** NOTE NOTE NOTE NOTE NOTE ***** # To override the automatic Linux source tree determination, pass the @@ -75,8 +75,9 @@ INC= /usr/include CFLAGS= -O2 $(WARNINGS) WARNINGS= -Wall -Wwrite-strings -Wpointer-arith -Wcast-align \ - -Wstrict-prototypes -Wshadow -Wnested-externs \ - -Winline -Wpointer-arith + -Wstrict-prototypes -Wnested-externs \ + -Wpointer-arith +# -Wshadow -Winline -- make output too noisy MODCFLAGS= $(CFLAGS) -D__KERNEL__ -DMODULE -fomit-frame-pointer PRGCFLAGS= $(CFLAGS) -g -ansi -pedantic -DPOSIX_C_SOURCE=199309L \ -D_POSIX_SOURCE -D_XOPEN_SOURCE -D_BSD_SOURCE -D_SVID_SOURCE \ @@ -120,7 +121,9 @@ all:; @echo Error: Could not locate kernel tree in $A $B $C else SMP := $(shell gcc -E -nostdinc -I$(TREE) picker.c 2>/dev/null \ | grep -s 'SMP = ' | cut -d' ' -f3) -MODVERSIONS := $(shell gcc -E -I $(TREE) picker.c 2>/dev/null \ +MODULES := $(shell gcc -E -nostdinc -I $(TREE) picker.c 2>/dev/null \ + | grep -s 'MODULES = ' | cut -d' ' -f3) +MODVERSIONS := $(shell gcc -E -nostdinc -I $(TREE) picker.c 2>/dev/null \ | grep -s 'MODVERSIONS = ' | cut -d' ' -f3) AGP := $(shell gcc -E -nostdinc -I$(TREE) picker.c 2>/dev/null \ | grep -s 'AGP = ' | cut -d' ' -f3) @@ -132,7 +135,7 @@ AGP := $(shell gcc -E -nostdinc -I$(TREE) picker.c 2>/dev/null \ endif ifeq ($(AGP),1) -MODCFLAGS += -DDRM_AGP +MODCFLAGS += -DCONFIG_AGP -DCONFIG_AGP_MODULE DRMOBJS += agpsupport.o MODS += mga.o i810.o @@ -144,11 +147,19 @@ I810HEADERS= i810_drv.h $(DRMHEADERS) endif all::;@echo === KERNEL HEADERS IN $(TREE) -all::;@echo === SMP=${SMP} MODVERSIONS=${MODVERSIONS} AGP=${AGP} +all::;@echo === SMP=${SMP} MODULES=${MODULES} MODVERSIONS=${MODVERSIONS} AGP=${AGP} all::;@echo === kill_fasync has $(PARAMS) parameters + +ifeq ($(MODULES),0) +all::;@echo +all::;@echo "*** Kernel modules must be configured. Build aborted." +all::;@echo +else all:: $(LIBS) $(MODS) $(PROGS) endif +endif + # **** End of SMP/MODVERSIONS detection # **** Handle SMP/MODVERSIONS @@ -168,12 +179,18 @@ libdrm.a: $(DRMOBJS) -$(RM) -f $@ $(AR) rcs $@ $(DRMOBJS) +gamma_drv.o: gamma_drv.c + $(CC) $(MODCFLAGS) -DEXPORT_SYMTAB -I$(TREE) -c $< -o $@ gamma.o: $(GAMMAOBJS) $(LIBS) $(LD) -r $^ -o $@ +tdfx_drv.o: tdfx_drv.c + $(CC) $(MODCFLAGS) -DEXPORT_SYMTAB -I$(TREE) -c $< -o $@ tdfx.o: $(TDFXOBJS) $(LIBS) $(LD) -r $^ -o $@ +r128_drv.o: r128_drv.c + $(CC) $(MODCFLAGS) -DEXPORT_SYMTAB -I$(TREE) -c $< -o $@ r128.o: $(R128OBJS) $(LIBS) $(LD) -r $^ -o $@ @@ -181,9 +198,13 @@ sis.o: $(SISOBJS) $(LIBS) $(LD) -r $^ -o $@ ifeq ($(AGP),1) +mga_drv.o: mga_drv.c + $(CC) $(MODCFLAGS) -DEXPORT_SYMTAB -I$(TREE) -c $< -o $@ mga.o: $(MGAOBJS) $(LIBS) $(LD) -r $^ -o $@ +i810_drv.o: i810_drv.c + $(CC) $(MODCFLAGS) -DEXPORT_SYMTAB -I$(TREE) -c $< -o $@ i810.o: $(I810OBJS) $(LIBS) $(LD) -r $^ -o $@ endif @@ -195,7 +216,9 @@ drmstat: $(PROGOBJS) ChangeLog: @rm -f Changelog @rcs2log -i 2 -r -l \ - | sed 's,@.*alephnull.com,@precisioninsight.com,' > ChangeLog + | sed 's,@.*light,,' \ + | sed 's,/cvsroot/.*/drm/kernel/,,g' \ + > ChangeLog # .o files are used for modules @@ -205,7 +228,6 @@ ChangeLog: %.po: %.c $(CC) $(PRGCFLAGS) -DDRM_USE_MALLOC -c $< -o $@ - $(DRMOBJS): $(DRMHEADERS) $(GAMMAOBJS): $(GAMMAHEADERS) $(TDFXOBJS): $(TDFXHEADERS) diff --git a/linux/README.drm b/linux/README.drm index 1cc4c277..b48b7b67 100644 --- a/linux/README.drm +++ b/linux/README.drm @@ -1,3 +1,9 @@ +/* $XFree86$ */ + +************************************************************ +* For the very latest on DRI development, please see: * +* http://dri.sourceforge.net/ * +************************************************************ The Direct Rendering Manager (drm) is a device-independent kernel-level device driver that provides support for the XFree86 Direct Rendering @@ -36,6 +42,7 @@ For specific information about kernel-level support, see: A Security Analysis of the Direct Rendering Infrastructure http://precisioninsight.com/dr/security.html - - -$XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/README.drm,v 1.2 1999/09/27 14:59:24 dawes Exp $ +************************************************************ +* For the very latest on DRI development, please see: * +* http://dri.sourceforge.net/ * +************************************************************ diff --git a/linux/agpsupport.c b/linux/agpsupport.c index c89c3e25..6a9f78c2 100644 --- a/linux/agpsupport.c +++ b/linux/agpsupport.c @@ -28,8 +28,11 @@ * */ +/* $XFree86$ */ + #define __NO_VERSION__ #include "drmP.h" +#include <linux/module.h> drm_agp_func_t drm_agp = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; @@ -286,25 +289,44 @@ 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; - case INTEL_LX: head->chipset = "Intel 440LX"; break; - case INTEL_BX: head->chipset = "Intel 440BX"; break; - case INTEL_GX: head->chipset = "Intel 440GX"; break; - case INTEL_I810: head->chipset = "Intel i810"; break; - case VIA_GENERIC: head->chipset = "VIA"; break; - case VIA_VP3: head->chipset = "VIA VP3"; break; - case VIA_MVP3: head->chipset = "VIA MVP3"; break; - case VIA_APOLLO_PRO: head->chipset = "VIA Apollo Pro"; 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: + case INTEL_GENERIC: head->chipset = "Intel"; break; + case INTEL_LX: head->chipset = "Intel 440LX"; break; + 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; + case VIA_APOLLO_KX133: head->chipset = "VIA Apollo KX133"; + break; + case VIA_APOLLO_KT133: head->chipset = "VIA Apollo KT133"; + break; +#endif + + case VIA_APOLLO_PRO: head->chipset = "VIA Apollo Pro"; + 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: head->chipset = "Unknown"; break; } - DRM_INFO("AGP %d.%d on %s @ 0x%08lx %dMB\n", + DRM_INFO("AGP %d.%d on %s @ 0x%08lx %ZuMB\n", head->agp_info.version.major, head->agp_info.version.minor, head->chipset, @@ -313,3 +335,15 @@ drm_agp_head_t *drm_agp_init(void) } return head; } + +void drm_agp_uninit(void) +{ + drm_agp_fill_t *fill; + + for (fill = &drm_agp_fill[0]; fill->name; fill++) { +#if LINUX_VERSION_CODE >= 0x020400 + if ((*fill->f).address) put_module_symbol((*fill->f).address); +#endif + (*fill->f).address = 0; + } +} diff --git a/linux/auth.c b/linux/auth.c index 9f81c539..a58bdd01 100644 --- a/linux/auth.c +++ b/linux/auth.c @@ -28,6 +28,7 @@ * Rickard E. (Rik) Faith <faith@valinux.com> * */ +/* $XFree86$ */ #define __NO_VERSION__ #include "drmP.h" @@ -126,12 +127,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/linux/bufs.c b/linux/bufs.c index 011e4241..66bfc19e 100644 --- a/linux/bufs.c +++ b/linux/bufs.c @@ -28,6 +28,7 @@ * Rickard E. (Rik) Faith <faith@valinux.com> * */ +/* $XFree86$ */ #define __NO_VERSION__ #include <linux/config.h> @@ -72,12 +73,14 @@ int drm_addmap(struct inode *inode, struct file *filp, unsigned int cmd, switch (map->type) { case _DRM_REGISTERS: - case _DRM_FRAME_BUFFER: + case _DRM_FRAME_BUFFER: +#ifndef __sparc__ if (map->offset + map->size < map->offset || map->offset < virt_to_phys(high_memory)) { drm_free(map, sizeof(*map), DRM_MEM_MAPS); return -EINVAL; } +#endif #ifdef CONFIG_MTRR if (map->type == _DRM_FRAME_BUFFER || (map->flags & _DRM_WRITE_COMBINING)) { @@ -104,7 +107,7 @@ int drm_addmap(struct inode *inode, struct file *filp, unsigned int cmd, dev->lock.hw_lock = map->handle; /* Pointer to lock */ } break; -#ifdef DRM_AGP +#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) case _DRM_AGP: map->offset = map->offset + dev->agp->base; break; @@ -484,8 +487,10 @@ int drm_mapbufs(struct inode *inode, struct file *filp, unsigned int cmd, -EFAULT); if (request.count >= dma->buf_count) { + down(¤t->mm->mmap_sem); virtual = do_mmap(filp, 0, dma->byte_count, PROT_READ|PROT_WRITE, MAP_SHARED, 0); + up(¤t->mm->mmap_sem); if (virtual > -1024UL) { /* Real error */ retcode = (signed long)virtual; diff --git a/linux/drm.h b/linux/drm.h index 5a979e1c..44e2d397 100644 --- a/linux/drm.h +++ b/linux/drm.h @@ -31,11 +31,16 @@ * Dec 1999, Richard Henderson <rth@twiddle.net>, move to generic cmpxchg. * */ +/* $XFree86$ */ #ifndef _DRM_H_ #define _DRM_H_ +#if defined(__linux__) #include <asm/ioctl.h> /* For _IO* macros */ +#elif defined(__FreeBSD__) +#include <sys/ioccom.h> +#endif #define DRM_PROC_DEVICES "/proc/devices" #define DRM_PROC_MISC "/proc/misc" @@ -289,7 +294,11 @@ typedef struct drm_agp_info { } drm_agp_info_t; #define DRM_IOCTL_BASE 'd' +#if defined(__linux__) #define DRM_IOCTL_NR(n) _IOC_NR(n) +#elif defined(__FreeBSD__) +#define DRM_IOCTL_NR(n) ((n) & 0xff) +#endif #define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr) #define DRM_IOR(nr,size) _IOR(DRM_IOCTL_BASE,nr,size) #define DRM_IOW(nr,size) _IOW(DRM_IOCTL_BASE,nr,size) diff --git a/linux/drmP.h b/linux/drmP.h index 9ad83bde..e47c0892 100644 --- a/linux/drmP.h +++ b/linux/drmP.h @@ -28,6 +28,7 @@ * Rickard E. (Rik) Faith <faith@valinux.com> * */ +/* $XFree86$ */ #ifndef _DRM_P_H_ #define _DRM_P_H_ @@ -44,13 +45,16 @@ #include <linux/pci.h> #include <linux/wrapper.h> #include <linux/version.h> +#include <linux/sched.h> +#include <linux/smp_lock.h> /* For (un)lock_kernel */ +#include <linux/mm.h> #include <asm/io.h> #include <asm/mman.h> #include <asm/uaccess.h> #ifdef CONFIG_MTRR #include <asm/mtrr.h> #endif -#ifdef DRM_AGP +#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) #include <linux/types.h> #include <linux/agp_backend.h> #endif @@ -129,6 +133,19 @@ typedef struct wait_queue *wait_queue_head_t; #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 @@ -312,6 +329,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 { @@ -399,7 +417,7 @@ typedef struct drm_device_dma { wait_queue_head_t waiting; /* Processes waiting on free bufs */ } drm_device_dma_t; -#ifdef DRM_AGP +#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) typedef struct drm_agp_mem { unsigned long handle; agp_memory *memory; @@ -488,9 +506,9 @@ typedef struct drm_device { /* Context support */ int irq; /* Interrupt used by board */ - __volatile__ int context_flag; /* Context swapping flag */ - __volatile__ int interrupt_flag;/* Interruption handler flag */ - __volatile__ int dma_flag; /* DMA dispatch flag */ + __volatile__ long context_flag; /* Context swapping flag */ + __volatile__ long interrupt_flag; /* Interruption handler flag */ + __volatile__ long dma_flag; /* DMA dispatch flag */ struct timer_list timer; /* Timer for delaying ctx switch */ wait_queue_head_t context_wait; /* Processes waiting on ctx switch */ int last_checked; /* Last context checked for DMA */ @@ -513,7 +531,7 @@ typedef struct drm_device { wait_queue_head_t buf_readers; /* Processes waiting to read */ wait_queue_head_t buf_writers; /* Processes waiting to ctx switch */ -#ifdef DRM_AGP +#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) drm_agp_head_t *agp; #endif unsigned long *ctx_bitmap; @@ -548,6 +566,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); @@ -559,6 +580,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); @@ -590,7 +614,7 @@ extern void drm_free_pages(unsigned long address, int order, extern void *drm_ioremap(unsigned long offset, unsigned long size); extern void drm_ioremapfree(void *pt, unsigned long size); -#ifdef DRM_AGP +#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) extern agp_memory *drm_alloc_agp(int pages, u32 type); extern int drm_free_agp(agp_memory *handle, int pages); extern int drm_bind_agp(agp_memory *handle, unsigned int start); @@ -633,7 +657,6 @@ extern void drm_free_buffer(drm_device_t *dev, drm_buf_t *buf); extern void drm_reclaim_buffers(drm_device_t *dev, pid_t pid); extern int drm_context_switch(drm_device_t *dev, int old, int new); extern int drm_context_switch_complete(drm_device_t *dev, int new); -extern void drm_wakeup(drm_device_t *dev, drm_buf_t *buf); extern void drm_clear_next_buffer(drm_device_t *dev); extern int drm_select_queue(drm_device_t *dev, void (*wrapper)(unsigned long)); @@ -714,9 +737,10 @@ extern void drm_ctxbitmap_cleanup(drm_device_t *dev); extern int drm_ctxbitmap_next(drm_device_t *dev); extern void drm_ctxbitmap_free(drm_device_t *dev, int ctx_handle); -#ifdef DRM_AGP +#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) /* AGP/GART support (agpsupport.c) */ extern drm_agp_head_t *drm_agp_init(void); +extern void drm_agp_uninit(void); extern int drm_agp_acquire(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); extern int drm_agp_release(struct inode *inode, struct file *filp, diff --git a/linux/fops.c b/linux/fops.c index 4ade7aa1..a839a6d9 100644 --- a/linux/fops.c +++ b/linux/fops.c @@ -29,6 +29,7 @@ * Daryll Strauss <daryll@valinux.com> * */ +/* $XFree86$ */ #define __NO_VERSION__ #include "drmP.h" @@ -94,7 +95,8 @@ int drm_release(struct inode *inode, struct file *filp) DRM_DEBUG("pid = %d, device = 0x%x, open_count = %d\n", current->pid, dev->device, dev->open_count); - if (_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) + if (dev->lock.hw_lock + && _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) && dev->lock.pid == current->pid) { DRM_ERROR("Process %d dead, freeing lock for context %d\n", current->pid, @@ -222,8 +224,15 @@ int drm_write_string(drm_device_t *dev, const char *s) KILLFASYNCHASTHREEPARAMETERS if three parameters are found. */ if (dev->buf_async) kill_fasync(dev->buf_async, SIGIO); #else - /* Parameter added in 2.3.21 */ + + /* Parameter added in 2.3.21. */ +#if LINUX_VERSION_CODE < 0x020400 if (dev->buf_async) kill_fasync(dev->buf_async, SIGIO, POLL_IN); +#else + /* Type of first parameter changed in + Linux 2.4.0-test2... */ + if (dev->buf_async) kill_fasync(&dev->buf_async, SIGIO, POLL_IN); +#endif #endif DRM_DEBUG("waking\n"); wake_up_interruptible(&dev->buf_readers); diff --git a/linux/gamma_drv.c b/linux/gamma_drv.c index 987c903d..5d4c3ba9 100644 --- a/linux/gamma_drv.c +++ b/linux/gamma_drv.c @@ -28,14 +28,11 @@ * Rickard E. (Rik) Faith <faith@valinux.com> * */ +/* $XFree86$ */ #include <linux/config.h> -#define EXPORT_SYMTAB #include "drmP.h" #include "gamma_drv.h" -#include <linux/pci.h> -EXPORT_SYMBOL(gamma_init); -EXPORT_SYMBOL(gamma_cleanup); #ifndef PCI_DEVICE_ID_3DLABS_GAMMA #define PCI_DEVICE_ID_3DLABS_GAMMA 0x0008 @@ -46,7 +43,7 @@ EXPORT_SYMBOL(gamma_cleanup); #define GAMMA_NAME "gamma" #define GAMMA_DESC "3dlabs GMX 2000" -#define GAMMA_DATE "20000606" +#define GAMMA_DATE "20000719" #define GAMMA_MAJOR 1 #define GAMMA_MINOR 0 #define GAMMA_PATCHLEVEL 0 @@ -54,6 +51,10 @@ EXPORT_SYMBOL(gamma_cleanup); static drm_device_t gamma_device; static struct file_operations gamma_fops = { +#if LINUX_VERSION_CODE >= 0x020400 + /* This started being used during 2.4.0-test */ + owner: THIS_MODULE, +#endif open: gamma_open, flush: drm_flush, release: gamma_release, @@ -105,49 +106,30 @@ static drm_ioctl_desc_t gamma_ioctls[] = { #define GAMMA_IOCTL_COUNT DRM_ARRAY_SIZE(gamma_ioctls) #ifdef MODULE -int init_module(void); -void cleanup_module(void); static char *gamma = NULL; +#endif static int devices = 0; -MODULE_AUTHOR("Precision Insight, Inc., Cedar Park, Texas."); +MODULE_AUTHOR("VA Linux Systems, Inc."); MODULE_DESCRIPTION("3dlabs GMX 2000"); MODULE_PARM(gamma, "s"); MODULE_PARM(devices, "i"); -MODULE_PARM_DESC(devices, "devices=x, where x is the number of MX chips on your card\n"); - -/* init_module is called when insmod is used to load the module */ - -int init_module(void) -{ - return gamma_init(); -} - -/* cleanup_module is called when rmmod is used to unload the module */ - -void cleanup_module(void) -{ - gamma_cleanup(); -} -#endif - +MODULE_PARM_DESC(devices, + "devices=x, where x is the number of MX chips on card\n"); #ifndef MODULE -/* gamma_setup is called by the kernel to parse command-line options passed - * via the boot-loader (e.g., LILO). It calls the insmod option routine, - * drm_parse_options. - * - * This is not currently supported, since it requires changes to - * linux/init/main.c. */ +/* gamma_options is called by the kernel to parse command-line options + * passed via the boot-loader (e.g., LILO). It calls the insmod option + * routine, drm_parse_options. + */ -void __init gamma_setup(char *str, int *ints) +static int __init gamma_options(char *str) { - if (ints[0] != 0) { - DRM_ERROR("Illegal command line format, ignored\n"); - return; - } drm_parse_options(str); + return 1; } + +__setup("gamma=", gamma_options); #endif static int gamma_setup(drm_device_t *dev) @@ -284,12 +266,10 @@ static int gamma_takedown(drm_device_t *dev) - PAGE_SHIFT, DRM_MEM_SAREA); break; -#ifdef DRM_AGP case _DRM_AGP: /* Do nothing here, because this is all handled in the AGP/GART driver. */ break; -#endif } drm_free(map, sizeof(*map), DRM_MEM_MAPS); } @@ -360,7 +340,7 @@ int gamma_find_devices(void) /* gamma_init is called via init_module at module load time, or via * linux/init/main.c (this is not currently supported). */ -int gamma_init(void) +static int gamma_init(void) { int retcode; drm_device_t *dev = &gamma_device; @@ -401,7 +381,7 @@ int gamma_init(void) /* gamma_cleanup is called via cleanup_module at module unload time. */ -void gamma_cleanup(void) +static void gamma_cleanup(void) { drm_device_t *dev = &gamma_device; @@ -416,6 +396,10 @@ void gamma_cleanup(void) gamma_takedown(dev); } +module_init(gamma_init); +module_exit(gamma_cleanup); + + int gamma_version(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { @@ -457,7 +441,9 @@ int gamma_open(struct inode *inode, struct file *filp) DRM_DEBUG("open_count = %d\n", dev->open_count); if (!(retcode = drm_open_helper(inode, filp, dev))) { - MOD_INC_USE_COUNT; +#if LINUX_VERSION_CODE < 0x020333 + MOD_INC_USE_COUNT; /* Needed before Linux 2.3.51 */ +#endif atomic_inc(&dev->total_open); spin_lock(&dev->count_lock); if (!dev->open_count++) { @@ -472,12 +458,17 @@ int gamma_open(struct inode *inode, struct file *filp) int gamma_release(struct inode *inode, struct file *filp) { drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; + drm_device_t *dev; int retcode = 0; + lock_kernel(); + dev = priv->dev; + DRM_DEBUG("open_count = %d\n", dev->open_count); if (!(retcode = drm_release(inode, filp))) { - MOD_DEC_USE_COUNT; +#if LINUX_VERSION_CODE < 0x020333 + MOD_DEC_USE_COUNT; /* Needed before Linux 2.3.51 */ +#endif atomic_inc(&dev->total_close); spin_lock(&dev->count_lock); if (!--dev->open_count) { @@ -486,13 +477,16 @@ int gamma_release(struct inode *inode, struct file *filp) atomic_read(&dev->ioctl_count), dev->blocked); spin_unlock(&dev->count_lock); + unlock_kernel(); return -EBUSY; } spin_unlock(&dev->count_lock); + unlock_kernel(); return gamma_takedown(dev); } spin_unlock(&dev->count_lock); } + unlock_kernel(); return retcode; } diff --git a/linux/gamma_drv.h b/linux/gamma_drv.h index d7e70f7f..e50fb3f7 100644 --- a/linux/gamma_drv.h +++ b/linux/gamma_drv.h @@ -25,16 +25,15 @@ * DEALINGS IN THE SOFTWARE. * * Authors: - * Rickard E. (Rik) Faith <faith@precisioninsight.com> + * Rickard E. (Rik) Faith <faith@valinux.com> * */ +/* $XFree86$ */ #ifndef _GAMMA_DRV_H_ #define _GAMMA_DRV_H_ /* gamma_drv.c */ -extern int gamma_init(void); -extern void gamma_cleanup(void); extern int gamma_version(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); extern int gamma_open(struct inode *inode, struct file *filp); diff --git a/linux/i810_context.c b/linux/i810_context.c index 689814db..5dd440cb 100644 --- a/linux/i810_context.c +++ b/linux/i810_context.c @@ -28,8 +28,7 @@ * Jeff Hartmann <jhartmann@valinux.com> * */ - -#include <linux/sched.h> +/* $XFree86$ */ #define __NO_VERSION__ #include "drmP.h" diff --git a/linux/i810_dma.c b/linux/i810_dma.c index 901be559..1a8290df 100644 --- a/linux/i810_dma.c +++ b/linux/i810_dma.c @@ -29,11 +29,11 @@ * Keith Whitwell <keithw@valinux.com> * */ +/* $XFree86$ */ #define __NO_VERSION__ #include "drmP.h" #include "i810_drv.h" - #include <linux/interrupt.h> /* For task queue support */ /* in case we don't have a 2.3.99-pre6 kernel or later: */ @@ -156,16 +156,23 @@ static struct file_operations i810_buffer_fops = { int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; - drm_i810_private_t *dev_priv = dev->dev_private; - drm_buf_t *buf = dev_priv->mmap_buffer; - drm_i810_buf_priv_t *buf_priv = buf->dev_private; + drm_file_t *priv = filp->private_data; + drm_device_t *dev; + drm_i810_private_t *dev_priv; + drm_buf_t *buf; + drm_i810_buf_priv_t *buf_priv; + + lock_kernel(); + dev = priv->dev; + dev_priv = dev->dev_private; + buf = dev_priv->mmap_buffer; + buf_priv = buf->dev_private; vma->vm_flags |= (VM_IO | VM_DONTCOPY); vma->vm_file = filp; buf_priv->currently_mapped = I810_BUF_MAPPED; + unlock_kernel(); if (remap_page_range(vma->vm_start, VM_OFFSET(vma), @@ -276,8 +283,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; } @@ -287,9 +294,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; } diff --git a/linux/i810_drv.c b/linux/i810_drv.c index d7fa9d88..3dc5c6af 100644 --- a/linux/i810_drv.c +++ b/linux/i810_drv.c @@ -28,19 +28,15 @@ * Jeff Hartmann <jhartmann@valinux.com> * */ +/* $XFree86$ */ #include <linux/config.h> -#define EXPORT_SYMTAB #include "drmP.h" #include "i810_drv.h" - -EXPORT_SYMBOL(i810_init); -EXPORT_SYMBOL(i810_cleanup); - #define I810_NAME "i810" #define I810_DESC "Intel I810" -#define I810_DATE "19991213" +#define I810_DATE "20000719" #define I810_MAJOR 1 #define I810_MINOR 1 #define I810_PATCHLEVEL 0 @@ -49,6 +45,10 @@ static drm_device_t i810_device; drm_ctx_t i810_res_ctx; static struct file_operations i810_fops = { +#if LINUX_VERSION_CODE >= 0x020400 + /* This started being used during 2.4.0-test */ + owner: THIS_MODULE, +#endif open: i810_open, flush: drm_flush, release: i810_release, @@ -119,47 +119,26 @@ static drm_ioctl_desc_t i810_ioctls[] = { #define I810_IOCTL_COUNT DRM_ARRAY_SIZE(i810_ioctls) #ifdef MODULE -int init_module(void); -void cleanup_module(void); static char *i810 = NULL; +#endif -MODULE_AUTHOR("Precision Insight, Inc., Cedar Park, Texas."); +MODULE_AUTHOR("VA Linux Systems, Inc."); MODULE_DESCRIPTION("Intel I810"); MODULE_PARM(i810, "s"); -/* init_module is called when insmod is used to load the module */ - -int init_module(void) -{ - DRM_DEBUG("doing i810_init()\n"); - return i810_init(); -} - -/* cleanup_module is called when rmmod is used to unload the module */ - -void cleanup_module(void) -{ - i810_cleanup(); -} -#endif - #ifndef MODULE -/* i810_setup is called by the kernel to parse command-line options passed - * via the boot-loader (e.g., LILO). It calls the insmod option routine, - * drm_parse_drm. - * - * This is not currently supported, since it requires changes to - * linux/init/main.c. */ - +/* i810_options is called by the kernel to parse command-line options + * passed via the boot-loader (e.g., LILO). It calls the insmod option + * routine, drm_parse_drm. + */ -void __init i810_setup(char *str, int *ints) +static int __init i810_options(char *str) { - if (ints[0] != 0) { - DRM_ERROR("Illegal command line format, ignored\n"); - return; - } drm_parse_options(str); + return 1; } + +__setup("i810=", i810_options); #endif static int i810_setup(drm_device_t *dev) @@ -360,7 +339,7 @@ static int i810_takedown(drm_device_t *dev) /* i810_init is called via init_module at module load time, or via * linux/init/main.c (this is not currently supported). */ -int i810_init(void) +static int i810_init(void) { int retcode; drm_device_t *dev = &i810_device; @@ -419,7 +398,7 @@ int i810_init(void) /* i810_cleanup is called via cleanup_module at module unload time. */ -void i810_cleanup(void) +static void i810_cleanup(void) { drm_device_t *dev = &i810_device; @@ -434,11 +413,16 @@ void i810_cleanup(void) drm_ctxbitmap_cleanup(dev); i810_takedown(dev); if (dev->agp) { + drm_agp_uninit(); drm_free(dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS); dev->agp = NULL; } } +module_init(i810_init); +module_exit(i810_cleanup); + + int i810_version(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { @@ -480,7 +464,9 @@ int i810_open(struct inode *inode, struct file *filp) DRM_DEBUG("open_count = %d\n", dev->open_count); if (!(retcode = drm_open_helper(inode, filp, dev))) { - MOD_INC_USE_COUNT; +#if LINUX_VERSION_CODE < 0x020333 + MOD_INC_USE_COUNT; /* Needed before Linux 2.3.51 */ +#endif atomic_inc(&dev->total_open); spin_lock(&dev->count_lock); if (!dev->open_count++) { @@ -495,9 +481,11 @@ int i810_open(struct inode *inode, struct file *filp) int i810_release(struct inode *inode, struct file *filp) { drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; + drm_device_t *dev; int retcode = 0; + lock_kernel(); + dev = priv->dev; DRM_DEBUG("pid = %d, device = 0x%x, open_count = %d\n", current->pid, dev->device, dev->open_count); @@ -559,7 +547,9 @@ int i810_release(struct inode *inode, struct file *filp) up(&dev->struct_sem); drm_free(priv, sizeof(*priv), DRM_MEM_FILES); - MOD_DEC_USE_COUNT; +#if LINUX_VERSION_CODE < 0x020333 + MOD_DEC_USE_COUNT; /* Needed before Linux 2.3.51 */ +#endif atomic_inc(&dev->total_close); spin_lock(&dev->count_lock); if (!--dev->open_count) { @@ -568,12 +558,15 @@ int i810_release(struct inode *inode, struct file *filp) atomic_read(&dev->ioctl_count), dev->blocked); spin_unlock(&dev->count_lock); + unlock_kernel(); return -EBUSY; } spin_unlock(&dev->count_lock); - return i810_takedown(dev); + unlock_kernel(); + return i810_takedown(dev); } - spin_unlock(&dev->count_lock); + spin_unlock(&dev->count_lock); + unlock_kernel(); return retcode; } diff --git a/linux/i810_drv.h b/linux/i810_drv.h index f5411c0b..5586a6a6 100644 --- a/linux/i810_drv.h +++ b/linux/i810_drv.h @@ -28,6 +28,7 @@ * Jeff Hartmann <jhartmann@valinux.com> * */ +/* $XFree86$ */ #ifndef _I810_DRV_H_ #define _I810_DRV_H_ @@ -77,8 +78,6 @@ typedef struct drm_i810_private { } drm_i810_private_t; /* i810_drv.c */ -extern int i810_init(void); -extern void i810_cleanup(void); extern int i810_version(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); extern int i810_open(struct inode *inode, struct file *filp); diff --git a/linux/init.c b/linux/init.c index aefc884e..98189580 100644 --- a/linux/init.c +++ b/linux/init.c @@ -28,6 +28,7 @@ * Rickard E. (Rik) Faith <faith@valinux.com> * */ +/* $XFree86$ */ #define __NO_VERSION__ #include "drmP.h" @@ -97,10 +98,17 @@ void drm_parse_options(char *s) } } +/* drm_cpu_valid returns non-zero if the DRI will run on this CPU, and 0 + * otherwise. */ + int drm_cpu_valid(void) { #if defined(__i386__) if (boot_cpu_data.x86 == 3) return 0; /* No cmpxchg on a 386 */ #endif +#if defined(__sparc__) && !defined(__sparc_v9__) + if (1) + return 0; /* No cmpxchg before v9 sparc. */ +#endif return 1; } diff --git a/linux/lists.c b/linux/lists.c index f62495aa..2850d3b3 100644 --- a/linux/lists.c +++ b/linux/lists.c @@ -28,6 +28,7 @@ * Rickard E. (Rik) Faith <faith@valinux.com> * */ +/* $XFree86$ */ #define __NO_VERSION__ #include "drmP.h" @@ -116,6 +117,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 +132,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 +152,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,26 +174,21 @@ 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", diff --git a/linux/memory.c b/linux/memory.c index 0e92401b..3416698a 100644 --- a/linux/memory.c +++ b/linux/memory.c @@ -28,9 +28,12 @@ * Rickard E. (Rik) Faith <faith@valinux.com> * */ +/* $XFree86$ */ #define __NO_VERSION__ +#include <linux/config.h> #include "drmP.h" +#include <linux/wrapper.h> typedef struct drm_mem_stats { const char *name; @@ -197,7 +200,7 @@ void drm_free(void *pt, size_t size, int area) int free_count; if (!pt) DRM_MEM_ERROR(area, "Attempt to free NULL pointer\n"); - else kfree_s(pt, size); + else kfree(pt); spin_lock(&drm_mem_lock); drm_mem_stats[area].bytes_freed += size; free_count = ++drm_mem_stats[area].free_count; @@ -245,7 +248,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; @@ -266,7 +274,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); } @@ -330,7 +343,7 @@ void drm_ioremapfree(void *pt, unsigned long size) } } -#ifdef DRM_AGP +#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) agp_memory *drm_alloc_agp(int pages, u32 type) { agp_memory *handle; diff --git a/linux/mga_context.c b/linux/mga_context.c index d0259274..004fec14 100644 --- a/linux/mga_context.c +++ b/linux/mga_context.c @@ -28,8 +28,7 @@ * Jeff Hartmann <jhartmann@valinux.com> * */ - -#include <linux/sched.h> +/* $XFree86$ */ #define __NO_VERSION__ #include "drmP.h" diff --git a/linux/mga_dma.c b/linux/mga_dma.c index 28e8811c..1a1041a3 100644 --- a/linux/mga_dma.c +++ b/linux/mga_dma.c @@ -29,6 +29,7 @@ * Keith Whitwell <keithw@valinux.com> * */ +/* $XFree86$ */ #define __NO_VERSION__ #include "drmP.h" @@ -57,8 +58,8 @@ static unsigned long mga_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; } @@ -70,9 +71,9 @@ static void mga_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; } @@ -765,7 +766,7 @@ 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; DRM_DEBUG("chipset: %d ucode_size: %d backOffset: %x depthOffset: %x\n", dev_priv->chipset, dev_priv->warp_ucode_size, diff --git a/linux/mga_drv.c b/linux/mga_drv.c index e77d827b..ab1bc127 100644 --- a/linux/mga_drv.c +++ b/linux/mga_drv.c @@ -29,17 +29,15 @@ * * */ +/* $XFree86$ */ #include <linux/config.h> -#define EXPORT_SYMTAB #include "drmP.h" #include "mga_drv.h" -EXPORT_SYMBOL(mga_init); -EXPORT_SYMBOL(mga_cleanup); #define MGA_NAME "mga" #define MGA_DESC "Matrox g200/g400" -#define MGA_DATE "19991213" +#define MGA_DATE "20000719" #define MGA_MAJOR 1 #define MGA_MINOR 0 #define MGA_PATCHLEVEL 0 @@ -48,6 +46,10 @@ static drm_device_t mga_device; drm_ctx_t mga_res_ctx; static struct file_operations mga_fops = { +#if LINUX_VERSION_CODE >= 0x020400 + /* This started being used during 2.4.0-test */ + owner: THIS_MODULE, +#endif open: mga_open, flush: drm_flush, release: mga_release, @@ -118,47 +120,26 @@ static drm_ioctl_desc_t mga_ioctls[] = { #define MGA_IOCTL_COUNT DRM_ARRAY_SIZE(mga_ioctls) #ifdef MODULE -int init_module(void); -void cleanup_module(void); static char *mga = NULL; +#endif -MODULE_AUTHOR("Precision Insight, Inc., Cedar Park, Texas."); +MODULE_AUTHOR("VA Linux Systems, Inc."); MODULE_DESCRIPTION("Matrox g200/g400"); MODULE_PARM(mga, "s"); -/* init_module is called when insmod is used to load the module */ - -int init_module(void) -{ - DRM_DEBUG("doing mga_init()\n"); - return mga_init(); -} - -/* cleanup_module is called when rmmod is used to unload the module */ - -void cleanup_module(void) -{ - mga_cleanup(); -} -#endif - #ifndef MODULE -/* mga_setup is called by the kernel to parse command-line options passed +/* mga_options is called by the kernel to parse command-line options passed * via the boot-loader (e.g., LILO). It calls the insmod option routine, * drm_parse_drm. - * - * This is not currently supported, since it requires changes to - * linux/init/main.c. */ - + */ -void __init mga_setup(char *str, int *ints) +static int __init mga_options(char *str) { - if (ints[0] != 0) { - DRM_ERROR("Illegal command line format, ignored\n"); - return; - } drm_parse_options(str); + return 1; } + +__setup("mga=", mga_options); #endif static int mga_setup(drm_device_t *dev) @@ -357,7 +338,7 @@ static int mga_takedown(drm_device_t *dev) /* mga_init is called via init_module at module load time, or via * linux/init/main.c (this is not currently supported). */ -int mga_init(void) +static int mga_init(void) { int retcode; drm_device_t *dev = &mga_device; @@ -422,7 +403,7 @@ int mga_init(void) /* mga_cleanup is called via cleanup_module at module unload time. */ -void mga_cleanup(void) +static void mga_cleanup(void) { drm_device_t *dev = &mga_device; @@ -448,11 +429,16 @@ void mga_cleanup(void) mga_takedown(dev); if (dev->agp) { + drm_agp_uninit(); drm_free(dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS); dev->agp = NULL; } } +module_init(mga_init); +module_exit(mga_cleanup); + + int mga_version(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { @@ -494,7 +480,9 @@ int mga_open(struct inode *inode, struct file *filp) DRM_DEBUG("open_count = %d\n", dev->open_count); if (!(retcode = drm_open_helper(inode, filp, dev))) { - MOD_INC_USE_COUNT; +#if LINUX_VERSION_CODE < 0x020333 + MOD_INC_USE_COUNT; /* Needed before Linux 2.3.51 */ +#endif atomic_inc(&dev->total_open); spin_lock(&dev->count_lock); if (!dev->open_count++) { @@ -509,9 +497,11 @@ int mga_open(struct inode *inode, struct file *filp) int mga_release(struct inode *inode, struct file *filp) { drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; + drm_device_t *dev; int retcode = 0; + lock_kernel(); + dev = priv->dev; DRM_DEBUG("pid = %d, device = 0x%x, open_count = %d\n", current->pid, dev->device, dev->open_count); @@ -573,7 +563,9 @@ int mga_release(struct inode *inode, struct file *filp) up(&dev->struct_sem); drm_free(priv, sizeof(*priv), DRM_MEM_FILES); - MOD_DEC_USE_COUNT; +#if LINUX_VERSION_CODE < 0x020333 + MOD_DEC_USE_COUNT; /* Needed before Linux 2.3.51 */ +#endif atomic_inc(&dev->total_close); spin_lock(&dev->count_lock); if (!--dev->open_count) { @@ -582,12 +574,15 @@ int mga_release(struct inode *inode, struct file *filp) atomic_read(&dev->ioctl_count), dev->blocked); spin_unlock(&dev->count_lock); + unlock_kernel(); return -EBUSY; } spin_unlock(&dev->count_lock); + unlock_kernel(); return mga_takedown(dev); } - spin_unlock(&dev->count_lock); + spin_unlock(&dev->count_lock); + unlock_kernel(); return retcode; } diff --git a/linux/mga_drv.h b/linux/mga_drv.h index f217acb9..8ba77224 100644 --- a/linux/mga_drv.h +++ b/linux/mga_drv.h @@ -28,6 +28,7 @@ * Jeff Hartmann <jhartmann@valinux.com> * */ +/* $XFree86$ */ #ifndef _MGA_DRV_H_ #define _MGA_DRV_H_ @@ -39,8 +40,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; @@ -102,8 +103,6 @@ typedef struct _drm_mga_private { } drm_mga_private_t; /* mga_drv.c */ -extern int mga_init(void); -extern void mga_cleanup(void); extern int mga_version(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); extern int mga_open(struct inode *inode, struct file *filp); @@ -211,19 +210,27 @@ 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 { \ diff --git a/linux/mga_state.c b/linux/mga_state.c index 723ccc53..45e93868 100644 --- a/linux/mga_state.c +++ b/linux/mga_state.c @@ -28,12 +28,29 @@ * Keith Whitwell <keithw@valinux.com> * */ +/* $XFree86$ */ #define __NO_VERSION__ #include "drmP.h" #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 15 +#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) { @@ -60,8 +77,8 @@ static void mgaEmitClipRect(drm_mga_private_t * dev_priv, 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); } @@ -224,7 +241,6 @@ static void mgaG400EmitTex1(drm_mga_private_t * dev_priv) PRIMADVANCE(dev_priv); } -#define EMIT_PIPE 50 static void mgaG400EmitPipe(drm_mga_private_t * dev_priv) { drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; @@ -492,7 +508,6 @@ static void mga_dma_dispatch_tex_blit(drm_device_t * dev, y2 = length / 64; PRIM_OVERFLOW(dev, dev_priv, 30); - PRIMGETPTR(dev_priv); PRIMOUTREG(MGAREG_DSTORG, destOrg); PRIMOUTREG(MGAREG_MACCESS, 0x00000000); @@ -526,7 +541,6 @@ 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__); @@ -542,9 +556,8 @@ static void mga_dma_dispatch_vertex(drm_device_t * dev, drm_buf_t * buf) * 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) { @@ -592,7 +605,6 @@ 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__); @@ -606,9 +618,8 @@ static void mga_dma_dispatch_indices(drm_device_t * dev, * 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 { @@ -657,7 +668,6 @@ 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__); @@ -666,11 +676,7 @@ static void mga_dma_dispatch_clear(drm_device_t * dev, int flags, 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; @@ -741,14 +747,12 @@ 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 +762,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,7 +771,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; + unsigned int start = pbox[i].y1 * pixel_stride; DRM_DEBUG("dispatch swap %d,%d-%d,%d!\n", pbox[i].x1, pbox[i].y1, pbox[i].x2, pbox[i].y2); diff --git a/linux/picker.c b/linux/picker.c index 0bd8bfd5..11912740 100644 --- a/linux/picker.c +++ b/linux/picker.c @@ -1,3 +1,5 @@ +/* $XFree86$ */ + #include <linux/autoconf.h> #include <linux/version.h> @@ -5,6 +7,10 @@ #define CONFIG_SMP 0 #endif +#ifndef CONFIG_MODULES +#define CONFIG_MODULES 0 +#endif + #ifndef CONFIG_MODVERSIONS #define CONFIG_MODVERSIONS 0 #endif @@ -18,6 +24,7 @@ #endif SMP = CONFIG_SMP +MODULES = CONFIG_MODULES MODVERSIONS = CONFIG_MODVERSIONS AGP = CONFIG_AGP AGP_MODULE = CONFIG_AGP_MODULE diff --git a/linux/proc.c b/linux/proc.c index ba6dee00..25822fd5 100644 --- a/linux/proc.c +++ b/linux/proc.c @@ -27,6 +27,7 @@ * Authors: * Rickard E. (Rik) Faith <faith@valinux.com> */ +/* $XFree86$ */ #define __NO_VERSION__ #include "drmP.h" @@ -228,7 +229,7 @@ static int _drm_queues_info(char *buf, char **start, off_t offset, int len, atomic_inc(&q->use_count); DRM_PROC_PRINT_RET(atomic_dec(&q->use_count), "%5d/0x%03x %5d %5d" - " %5d/%c%c/%c%c%c %5d %10d %10d %10d\n", + " %5d/%c%c/%c%c%c %5Zd %10d %10d %10d\n", i, q->flags, atomic_read(&q->use_count), @@ -351,17 +352,21 @@ static int drm_clients_info(char *buf, char **start, off_t offset, int len, #if DRM_DEBUG_CODE +#define DRM_VMA_VERBOSE 0 + static int _drm_vma_info(char *buf, char **start, off_t offset, int len, int *eof, void *data) { drm_device_t *dev = (drm_device_t *)data; drm_vma_entry_t *pt; + struct vm_area_struct *vma; +#if DRM_VMA_VERBOSE + unsigned long i; + unsigned long address; pgd_t *pgd; pmd_t *pmd; pte_t *pte; - unsigned long i; - struct vm_area_struct *vma; - unsigned long address; +#endif #if defined(__i386__) unsigned int pgprot; #endif @@ -517,9 +522,9 @@ static int _drm_histo_info(char *buf, char **start, off_t offset, int len, } else { DRM_PROC_PRINT("lock none\n"); } - DRM_PROC_PRINT("context_flag 0x%08x\n", dev->context_flag); - DRM_PROC_PRINT("interrupt_flag 0x%08x\n", dev->interrupt_flag); - DRM_PROC_PRINT("dma_flag 0x%08x\n", dev->dma_flag); + DRM_PROC_PRINT("context_flag 0x%08lx\n", dev->context_flag); + DRM_PROC_PRINT("interrupt_flag 0x%08lx\n", dev->interrupt_flag); + DRM_PROC_PRINT("dma_flag 0x%08lx\n", dev->dma_flag); DRM_PROC_PRINT("queue_count %10d\n", dev->queue_count); DRM_PROC_PRINT("last_context %10d\n", dev->last_context); diff --git a/linux/r128_bufs.c b/linux/r128_bufs.c index e8ff4df4..19e389de 100644 --- a/linux/r128_bufs.c +++ b/linux/r128_bufs.c @@ -29,14 +29,16 @@ * Jeff Hartmann <jhartmann@valinux.com> * */ +/* $XFree86$ */ #define __NO_VERSION__ +#include <linux/config.h> #include "drmP.h" #include "r128_drv.h" #include "linux/un.h" -#ifdef DRM_AGP +#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) int r128_addbufs_agp(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { @@ -199,7 +201,7 @@ int r128_addbufs(struct inode *inode, struct file *filp, unsigned int cmd, sizeof(request), -EFAULT); -#ifdef DRM_AGP +#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) if (request.flags & _DRM_AGP_BUFFER) return r128_addbufs_agp(inode, filp, cmd, arg); else diff --git a/linux/r128_context.c b/linux/r128_context.c index f11453ba..a0df4d69 100644 --- a/linux/r128_context.c +++ b/linux/r128_context.c @@ -27,8 +27,7 @@ * Author: Rickard E. (Rik) Faith <faith@valinux.com> * */ - -#include <linux/sched.h> +/* $XFree86$ */ #define __NO_VERSION__ #include "drmP.h" @@ -38,10 +37,6 @@ extern drm_ctx_t r128_res_ctx; static int r128_alloc_queue(drm_device_t *dev) { -#if 0 - static int context = 0; -#endif - return drm_ctxbitmap_next(dev); } diff --git a/linux/r128_drv.c b/linux/r128_drv.c index 8b669888..9d768ce1 100644 --- a/linux/r128_drv.c +++ b/linux/r128_drv.c @@ -28,17 +28,15 @@ * Kevin E. Martin <martin@valinux.com> * */ +/* $XFree86$ */ #include <linux/config.h> -#define EXPORT_SYMTAB #include "drmP.h" #include "r128_drv.h" -EXPORT_SYMBOL(r128_init); -EXPORT_SYMBOL(r128_cleanup); #define R128_NAME "r128" -#define R128_DESC "r128" -#define R128_DATE "20000607" +#define R128_DESC "ATI Rage 128" +#define R128_DATE "20000719" #define R128_MAJOR 1 #define R128_MINOR 0 #define R128_PATCHLEVEL 0 @@ -47,6 +45,10 @@ static drm_device_t r128_device; drm_ctx_t r128_res_ctx; static struct file_operations r128_fops = { +#if LINUX_VERSION_CODE >= 0x020400 + /* This started being used during 2.4.0-test */ + owner: THIS_MODULE, +#endif open: r128_open, flush: drm_flush, release: r128_release, @@ -93,7 +95,7 @@ static drm_ioctl_desc_t r128_ioctls[] = { [DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = { r128_unlock, 1, 0 }, [DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = { drm_finish, 1, 0 }, -#ifdef DRM_AGP +#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) [DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = { drm_agp_acquire, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = { drm_agp_release, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = { drm_agp_enable, 1, 1 }, @@ -114,46 +116,26 @@ static drm_ioctl_desc_t r128_ioctls[] = { #define R128_IOCTL_COUNT DRM_ARRAY_SIZE(r128_ioctls) #ifdef MODULE -int init_module(void); -void cleanup_module(void); static char *r128 = NULL; +#endif -MODULE_AUTHOR("Precision Insight, Inc., Cedar Park, Texas."); +MODULE_AUTHOR("VA Linux Systems, Inc."); MODULE_DESCRIPTION("r128"); MODULE_PARM(r128, "s"); -/* init_module is called when insmod is used to load the module */ - -int init_module(void) -{ - return r128_init(); -} - -/* cleanup_module is called when rmmod is used to unload the module */ - -void cleanup_module(void) -{ - r128_cleanup(); -} -#endif - #ifndef MODULE -/* r128_setup is called by the kernel to parse command-line options passed - * via the boot-loader (e.g., LILO). It calls the insmod option routine, - * drm_parse_drm. - * - * This is not currently supported, since it requires changes to - * linux/init/main.c. */ - +/* r128_options is called by the kernel to parse command-line options + * passed via the boot-loader (e.g., LILO). It calls the insmod option + * routine, drm_parse_drm. + */ -void __init r128_setup(char *str, int *ints) +static int __init r128_options(char *str) { - if (ints[0] != 0) { - DRM_ERROR("Illegal command line format, ignored\n"); - return; - } drm_parse_options(str); + return 1; } + +__setup("r128=", r128_options); #endif static int r128_setup(drm_device_t *dev) @@ -255,7 +237,7 @@ static int r128_takedown(drm_device_t *dev) dev->magiclist[i].head = dev->magiclist[i].tail = NULL; } -#ifdef DRM_AGP +#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) /* Clear AGP information */ if (dev->agp) { drm_agp_mem_t *entry; @@ -342,7 +324,7 @@ static int r128_takedown(drm_device_t *dev) /* r128_init is called via init_module at module load time, or via * linux/init/main.c (this is not currently supported). */ -int r128_init(void) +static int r128_init(void) { int retcode; drm_device_t *dev = &r128_device; @@ -367,8 +349,15 @@ int r128_init(void) drm_mem_init(); drm_proc_init(dev); -#ifdef DRM_AGP +#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) dev->agp = drm_agp_init(); + if (dev->agp == NULL) { + DRM_ERROR("Cannot initialize agpgart module.\n"); + drm_proc_cleanup(); + misc_deregister(&r128_misc); + r128_takedown(dev); + return -ENOMEM; + } #ifdef CONFIG_MTRR dev->agp->agp_mtrr = mtrr_add(dev->agp->agp_info.aper_base, @@ -399,7 +388,7 @@ int r128_init(void) /* r128_cleanup is called via cleanup_module at module unload time. */ -void r128_cleanup(void) +static void r128_cleanup(void) { drm_device_t *dev = &r128_device; @@ -413,15 +402,19 @@ void r128_cleanup(void) } drm_ctxbitmap_cleanup(dev); r128_takedown(dev); -#ifdef DRM_AGP +#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) if (dev->agp) { - /* FIXME -- free other information, too */ + drm_agp_uninit(); drm_free(dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS); dev->agp = NULL; } #endif } +module_init(r128_init); +module_exit(r128_cleanup); + + int r128_version(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { @@ -463,7 +456,9 @@ int r128_open(struct inode *inode, struct file *filp) DRM_DEBUG("open_count = %d\n", dev->open_count); if (!(retcode = drm_open_helper(inode, filp, dev))) { - MOD_INC_USE_COUNT; +#if LINUX_VERSION_CODE < 0x020333 + MOD_INC_USE_COUNT; /* Needed before Linux 2.3.51 */ +#endif atomic_inc(&dev->total_open); spin_lock(&dev->count_lock); if (!dev->open_count++) { @@ -472,18 +467,23 @@ int r128_open(struct inode *inode, struct file *filp) } spin_unlock(&dev->count_lock); } + return retcode; } int r128_release(struct inode *inode, struct file *filp) { drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; + drm_device_t *dev; int retcode = 0; + lock_kernel(); + dev = priv->dev; DRM_DEBUG("open_count = %d\n", dev->open_count); if (!(retcode = drm_release(inode, filp))) { - MOD_DEC_USE_COUNT; +#if LINUX_VERSION_CODE < 0x020333 + MOD_DEC_USE_COUNT; /* Needed before Linux 2.3.51 */ +#endif atomic_inc(&dev->total_close); spin_lock(&dev->count_lock); if (!--dev->open_count) { @@ -492,13 +492,17 @@ int r128_release(struct inode *inode, struct file *filp) atomic_read(&dev->ioctl_count), dev->blocked); spin_unlock(&dev->count_lock); + unlock_kernel(); return -EBUSY; } spin_unlock(&dev->count_lock); + unlock_kernel(); return r128_takedown(dev); } spin_unlock(&dev->count_lock); } + + unlock_kernel(); return retcode; } @@ -664,19 +668,11 @@ int r128_lock(struct inode *inode, struct file *filp, unsigned int cmd, } } -#if 0 - DRM_ERROR("pid = %5d, old counter = %5ld\n", - current->pid, current->counter); -#endif +#if LINUX_VERSION_CODE < 0x020400 if (lock.context != r128_res_ctx.handle) { current->counter = 5; current->priority = DEF_PRIORITY/4; } -#if 0 - while (current->counter > 25) - current->counter >>= 1; /* decrease time slice */ - DRM_ERROR("pid = %5d, new counter = %5ld\n", - current->pid, current->counter); #endif DRM_DEBUG("%d %s\n", lock.context, ret ? "interrupted" : "has lock"); @@ -718,19 +714,11 @@ int r128_unlock(struct inode *inode, struct file *filp, unsigned int cmd, } } -#if 0 - current->policy |= SCHED_YIELD; - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(1000); -#endif - +#if LINUX_VERSION_CODE < 0x020400 if (lock.context != r128_res_ctx.handle) { current->counter = 5; current->priority = DEF_PRIORITY; } -#if 0 - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(10); #endif return 0; diff --git a/linux/r128_drv.h b/linux/r128_drv.h index 81390bb8..2e17ed1c 100644 --- a/linux/r128_drv.h +++ b/linux/r128_drv.h @@ -28,6 +28,7 @@ * Kevin E. Martin <martin@valinux.com> * */ +/* $XFree86$ */ #ifndef _R128_DRV_H_ #define _R128_DRV_H_ @@ -69,8 +70,6 @@ typedef struct drm_r128_buf_priv { } drm_r128_buf_priv_t; /* r128_drv.c */ -extern int r128_init(void); -extern void r128_cleanup(void); extern int r128_version(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); extern int r128_open(struct inode *inode, struct file *filp); diff --git a/linux/sis_drm_public.h b/linux/sis_drm_public.h index dd14a5a5..4d2447d2 100644 --- a/linux/sis_drm_public.h +++ b/linux/sis_drm_public.h @@ -1,3 +1,32 @@ +/* sis_drm_public.h -- Private header for Direct Rendering Manager -*- linux-c -*- + * Created: Mon Jan 4 10:05:05 1999 by sclin@sis.com.tw + * + * Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan. + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: + * Sung-Ching Lin <sclin@sis.com.tw> + * + */ /* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/sis_drm_public.h,v 1.2 2000/08/04 03:51:47 tsi Exp $ */ #ifndef _sis_drm_public_h_ diff --git a/linux/sis_drv.c b/linux/sis_drv.c index 1e8abb7f..9acfc1e4 100644 --- a/linux/sis_drv.c +++ b/linux/sis_drv.c @@ -1,7 +1,8 @@ -/* sis.c -- sis driver -*- linux-c -*- +/* sis_drv.c -- sis driver -*- linux-c -*- * Created: Thu Oct 7 10:38:32 1999 by faith@precisioninsight.com * - * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas. + * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. + * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -22,13 +23,14 @@ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. - * + * * Authors: - * Rickard E. (Rik) Faith <faith@precisioninsight.com> - * Daryll Strauss <daryll@precisioninsight.com> + * Rickard E. (Rik) Faith <faith@valinux.com> + * Daryll Strauss <daryll@valinux.com> + * Sung-Ching Lin <sclin@sis.com.tw> * */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/sis_drv.c,v 1.2 2000/08/04 03:51:47 tsi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/sis_drv.c,v 1.6 2000/08/28 02:43:16 tsi Exp $ */ #include <linux/config.h> #include "drmP.h" @@ -36,16 +38,20 @@ #include "sis_drv.h" #define SIS_NAME "sis" -#define SIS_DESC "sis" -#define SIS_DATE "19991009" -#define SIS_MAJOR 0 +#define SIS_DESC "SIS 300/630/540" +#define SIS_DATE "20000831" +#define SIS_MAJOR 1 #define SIS_MINOR 0 -#define SIS_PATCHLEVEL 1 +#define SIS_PATCHLEVEL 0 static drm_device_t sis_device; drm_ctx_t sis_res_ctx; static struct file_operations sis_fops = { +#if LINUX_VERSION_CODE >= 0x020400 + /* This started being used during 2.4.0-test */ + owner: THIS_MODULE, +#endif open: sis_open, flush: drm_flush, release: sis_release, @@ -71,14 +77,14 @@ static drm_ioctl_desc_t sis_ioctls[] = { [DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)] = { drm_setunique, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_BLOCK)] = { drm_block, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] = { drm_unblock, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = { drm_authmagic, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = { drm_addmap, 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = { sis_addctx, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = { sis_rmctx, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = { sis_modctx, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] = { sis_getctx, 1, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = { sis_switchctx, 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = { sis_switchctx, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)] = { sis_newctx, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)] = { sis_resctx, 1, 0 }, [DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)] = { drm_adddraw, 1, 1 }, @@ -86,18 +92,16 @@ static drm_ioctl_desc_t sis_ioctls[] = { [DRM_IOCTL_NR(DRM_IOCTL_LOCK)] = { sis_lock, 1, 0 }, [DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = { sis_unlock, 1, 0 }, [DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = { drm_finish, 1, 0 }, - -#ifdef DRM_AGP - [DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = { drm_agp_acquire, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = { drm_agp_release, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = { drm_agp_enable, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)] = { drm_agp_info, 1, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)] = { drm_agp_alloc, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = { drm_agp_free, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = { drm_agp_bind, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = { drm_agp_unbind, 1, 1 }, +#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) + [DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = {drm_agp_acquire, 1, 1}, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = {drm_agp_release, 1, 1}, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = {drm_agp_enable, 1, 1}, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)] = {drm_agp_info, 1, 1}, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)] = {drm_agp_alloc, 1, 1}, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = {drm_agp_free, 1, 1}, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = {drm_agp_bind, 1, 1}, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = {drm_agp_unbind, 1, 1}, #endif - /* FB Memory Management */ [DRM_IOCTL_NR(SIS_IOCTL_FB_ALLOC)] = { sis_fb_alloc, 1, 1 }, [DRM_IOCTL_NR(SIS_IOCTL_FB_FREE)] = { sis_fb_free, 1, 1 }, @@ -120,10 +124,25 @@ static drm_ioctl_desc_t sis_ioctls[] = { static char *sis = NULL; #endif -MODULE_AUTHOR("Precision Insight, Inc., Cedar Park, Texas."); +MODULE_AUTHOR("VA Linux Systems, Inc."); MODULE_DESCRIPTION("sis"); MODULE_PARM(sis, "s"); +#ifndef MODULE +/* sis_options is called by the kernel to parse command-line options + * passed via the boot-loader (e.g., LILO). It calls the insmod option + * routine, drm_parse_drm. + */ + +static int __init sis_options(char *str) +{ + drm_parse_options(str); + return 1; +} + +__setup("sis=", sis_options); +#endif + static int sis_setup(drm_device_t *dev) { int i; @@ -225,30 +244,22 @@ static int sis_takedown(drm_device_t *dev) } dev->magiclist[i].head = dev->magiclist[i].tail = NULL; } -#ifdef DRM_AGP - /* Clear AGP information */ +#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) + /* Clear AGP information */ if (dev->agp) { - drm_agp_mem_t *entry; - drm_agp_mem_t *nexte; - - /* Remove AGP resources, but leave dev->agp - intact until cleanup is called. */ - for (entry = dev->agp->memory; entry; entry = nexte) { - nexte = entry->next; - if (entry->bound) drm_unbind_agp(entry->memory); - drm_free_agp(entry->memory, entry->pages); - drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS); + drm_agp_mem_t *temp; + drm_agp_mem_t *temp_next; + + temp = dev->agp->memory; + while(temp != NULL) { + temp_next = temp->next; + drm_free_agp(temp->memory, temp->pages); + drm_free(temp, sizeof(*temp), DRM_MEM_AGPLISTS); + temp = temp_next; } - dev->agp->memory = NULL; - - if (dev->agp->acquired && drm_agp.release) - (*drm_agp.release)(); - - dev->agp->acquired = 0; - dev->agp->enabled = 0; - } + if (dev->agp->acquired) (*drm_agp.release)(); + } #endif - /* Clear vma list (only built for debugging) */ if (dev->vmalist) { for (vma = dev->vmalist; vma; vma = vma_next) { @@ -309,7 +320,7 @@ static int sis_takedown(drm_device_t *dev) /* sis_init is called via init_module at module load time, or via * linux/init/main.c (this is not currently supported). */ -int sis_init(void) +static int sis_init(void) { int retcode; drm_device_t *dev = &sis_device; @@ -333,27 +344,16 @@ int sis_init(void) drm_mem_init(); drm_proc_init(dev); - -#ifdef DRM_AGP - DRM_DEBUG("doing agp init\n"); +#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) dev->agp = drm_agp_init(); - if(dev->agp == NULL) { - /* TODO, if no agp, run MMIO mode */ - DRM_INFO("The sis drm module requires the agpgart module" - " to function correctly\nPlease load the agpgart" - " module before you load the mga module\n"); - drm_proc_cleanup(); - misc_deregister(&sis_misc); - sis_takedown(dev); - return -ENOMEM; - } -#ifdef CONFIG_MTRR - dev->agp->agp_mtrr = mtrr_add(dev->agp->agp_info.aper_base, - dev->agp->agp_info.aper_size * 1024 * 1024, - MTRR_TYPE_WRCOMB, - 1); -#endif #endif + if((retcode = drm_ctxbitmap_init(dev))) { + DRM_ERROR("Cannot allocate memory for context bitmap.\n"); + drm_proc_cleanup(); + misc_deregister(&sis_misc); + sis_takedown(dev); + return retcode; + } DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", SIS_NAME, @@ -368,7 +368,7 @@ int sis_init(void) /* sis_cleanup is called via cleanup_module at module unload time. */ -void sis_cleanup(void) +static void sis_cleanup(void) { drm_device_t *dev = &sis_device; @@ -380,27 +380,21 @@ void sis_cleanup(void) } else { DRM_INFO("Module unloaded\n"); } -#ifdef DRM_AGP -#ifdef CONFIG_MTRR - if(dev->agp && dev->agp->agp_mtrr) { - int retval; - retval = mtrr_del(dev->agp->agp_mtrr, - dev->agp->agp_info.aper_base, - dev->agp->agp_info.aper_size * 1024*1024); - DRM_DEBUG("mtrr_del = %d\n", retval); - } -#endif -#endif - + drm_ctxbitmap_cleanup(dev); sis_takedown(dev); -#ifdef DRM_AGP +#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) if (dev->agp) { + drm_agp_uninit(); drm_free(dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS); dev->agp = NULL; } #endif } +module_init(sis_init); +module_exit(sis_cleanup); + + int sis_version(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { @@ -439,11 +433,12 @@ int sis_open(struct inode *inode, struct file *filp) { drm_device_t *dev = &sis_device; int retcode = 0; - + DRM_DEBUG("open_count = %d\n", dev->open_count); - if (!(retcode = drm_open_helper(inode, filp, dev))) { - MOD_INC_USE_COUNT; +#if LINUX_VERSION_CODE < 0x020333 + MOD_INC_USE_COUNT; /* Needed before Linux 2.3.51 */ +#endif atomic_inc(&dev->total_open); spin_lock(&dev->count_lock); if (!dev->open_count++) { @@ -458,13 +453,17 @@ int sis_open(struct inode *inode, struct file *filp) int sis_release(struct inode *inode, struct file *filp) { drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; + drm_device_t *dev; int retcode = 0; - DRM_DEBUG("open_count = %d\n", dev->open_count); + lock_kernel(); + dev = priv->dev; + DRM_DEBUG("open_count = %d\n", dev->open_count); if (!(retcode = drm_release(inode, filp))) { - MOD_DEC_USE_COUNT; +#if LINUX_VERSION_CODE < 0x020333 + MOD_DEC_USE_COUNT; /* Needed before Linux 2.3.51 */ +#endif atomic_inc(&dev->total_close); spin_lock(&dev->count_lock); if (!--dev->open_count) { @@ -473,13 +472,17 @@ int sis_release(struct inode *inode, struct file *filp) atomic_read(&dev->ioctl_count), dev->blocked); spin_unlock(&dev->count_lock); + unlock_kernel(); return -EBUSY; } spin_unlock(&dev->count_lock); + unlock_kernel(); return sis_takedown(dev); } spin_unlock(&dev->count_lock); } + + unlock_kernel(); return retcode; } @@ -594,7 +597,9 @@ int sis_lock(struct inode *inode, struct file *filp, unsigned int cmd, /* Contention */ atomic_inc(&dev->total_sleeps); current->state = TASK_INTERRUPTIBLE; +#if 1 current->policy |= SCHED_YIELD; +#endif schedule(); if (signal_pending(current)) { ret = -ERESTARTSYS; @@ -643,11 +648,12 @@ int sis_lock(struct inode *inode, struct file *filp, unsigned int cmd, } } +#if LINUX_VERSION_CODE < 0x020400 if (lock.context != sis_res_ctx.handle) { current->counter = 5; current->priority = DEF_PRIORITY/4; } - +#endif DRM_DEBUG("%d %s\n", lock.context, ret ? "interrupted" : "has lock"); #if DRM_DMA_HISTOGRAM @@ -687,29 +693,13 @@ int sis_unlock(struct inode *inode, struct file *filp, unsigned int cmd, DRM_ERROR("\n"); } } - + +#if LINUX_VERSION_CODE < 0x020400 if (lock.context != sis_res_ctx.handle) { current->counter = 5; current->priority = DEF_PRIORITY; } - +#endif + return 0; } - -module_init(sis_init); -module_exit(sis_cleanup); - -#ifndef MODULE -/* - * sis_setup is called by the kernel to parse command-line options passed - * via the boot-loader (e.g., LILO). It calls the insmod option routine, - * drm_parse_options. - */ -static int __init sis_options(char *str) -{ - drm_parse_options(str); - return 1; -} - -__setup("sis=", sis_options); -#endif diff --git a/linux/sis_drv.h b/linux/sis_drv.h index 50f6efad..95236977 100644 --- a/linux/sis_drv.h +++ b/linux/sis_drv.h @@ -2,6 +2,7 @@ * Created: Thu Oct 7 10:40:04 1999 by faith@precisioninsight.com * * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. + * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. * All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -24,19 +25,17 @@ * DEALINGS IN THE SOFTWARE. * * Authors: - * Rickard E. (Rik) Faith <faith@precisioninsight.com> - * Daryll Strauss <daryll@precisioninsight.com> + * Rickard E. (Rik) Faith <faith@valinux.com> + * Daryll Strauss <daryll@valinux.com> + * Sung-Ching Lin <sclin@sis.com.tw> * */ - -/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/sis_drv.h,v 1.2 2000/08/04 03:51:47 tsi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/sis_drv.h,v 1.5 2000/08/28 02:43:16 tsi Exp $ */ #ifndef _SIS_DRV_H_ #define _SIS_DRV_H_ /* sis_drv.c */ -extern int sis_init(void); -extern void sis_cleanup(void); extern int sis_version(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); extern int sis_open(struct inode *inode, struct file *filp); @@ -77,7 +76,6 @@ int sis_fb_alloc(struct inode *inode, struct file *filp, unsigned int cmd, int sis_fb_free(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); - int sis_agp_init(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); int sis_agp_alloc(struct inode *inode, struct file *filp, unsigned int cmd, diff --git a/linux/sis_mm.c b/linux/sis_mm.c index e722b8bd..35a21bfe 100644 --- a/linux/sis_mm.c +++ b/linux/sis_mm.c @@ -1,14 +1,42 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/sis_mm.c,v 1.2 2000/08/04 03:51:48 tsi Exp $ */ +/* sis_mm.c -- Private header for Direct Rendering Manager -*- linux-c -*- + * Created: Mon Jan 4 10:05:05 1999 by sclin@sis.com.tw + * + * Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan. + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: + * Sung-Ching Lin <sclin@sis.com.tw> + * + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/sis_mm.c,v 1.3 2000/08/25 13:42:46 dawes Exp $ */ #define __NO_VERSION__ -#include <linux/fb.h> -#include <linux/sisfb.h> -#include <linux/interrupt.h> - #include "drmP.h" #include "sis_drm_public.h" #include "sis_ds.h" #include "sis_drv.h" +#include <linux/fb.h> +#include <linux/sisfb.h> +#include <linux/interrupt.h> #define MAX_CONTEXT 100 #define VIDEO_TYPE 0 diff --git a/linux/tdfx_context.c b/linux/tdfx_context.c index c8d6e50e..6371cfc4 100644 --- a/linux/tdfx_context.c +++ b/linux/tdfx_context.c @@ -29,8 +29,7 @@ * Daryll Strauss <daryll@valinux.com> * */ - -#include <linux/sched.h> +/* $XFree86$ */ #define __NO_VERSION__ #include "drmP.h" diff --git a/linux/tdfx_drv.c b/linux/tdfx_drv.c index 582832b5..9cc3c993 100644 --- a/linux/tdfx_drv.c +++ b/linux/tdfx_drv.c @@ -29,17 +29,15 @@ * Daryll Strauss <daryll@valinux.com> * */ +/* $XFree86$ */ #include <linux/config.h> -#define EXPORT_SYMTAB #include "drmP.h" #include "tdfx_drv.h" -EXPORT_SYMBOL(tdfx_init); -EXPORT_SYMBOL(tdfx_cleanup); #define TDFX_NAME "tdfx" -#define TDFX_DESC "tdfx" -#define TDFX_DATE "19991009" +#define TDFX_DESC "3dfx Banshee/Voodoo3+" +#define TDFX_DATE "20000719" #define TDFX_MAJOR 1 #define TDFX_MINOR 0 #define TDFX_PATCHLEVEL 0 @@ -48,6 +46,10 @@ static drm_device_t tdfx_device; drm_ctx_t tdfx_res_ctx; static struct file_operations tdfx_fops = { +#if LINUX_VERSION_CODE >= 0x020400 + /* This started being used during 2.4.0-test */ + owner: THIS_MODULE, +#endif open: tdfx_open, flush: drm_flush, release: tdfx_release, @@ -88,7 +90,7 @@ static drm_ioctl_desc_t tdfx_ioctls[] = { [DRM_IOCTL_NR(DRM_IOCTL_LOCK)] = { tdfx_lock, 1, 0 }, [DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = { tdfx_unlock, 1, 0 }, [DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = { drm_finish, 1, 0 }, -#ifdef DRM_AGP +#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) [DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = {drm_agp_acquire, 1, 1}, [DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = {drm_agp_release, 1, 1}, [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = {drm_agp_enable, 1, 1}, @@ -102,46 +104,26 @@ static drm_ioctl_desc_t tdfx_ioctls[] = { #define TDFX_IOCTL_COUNT DRM_ARRAY_SIZE(tdfx_ioctls) #ifdef MODULE -int init_module(void); -void cleanup_module(void); static char *tdfx = NULL; +#endif -MODULE_AUTHOR("Precision Insight, Inc., Cedar Park, Texas."); +MODULE_AUTHOR("VA Linux Systems, Inc."); MODULE_DESCRIPTION("tdfx"); MODULE_PARM(tdfx, "s"); -/* init_module is called when insmod is used to load the module */ - -int init_module(void) -{ - return tdfx_init(); -} - -/* cleanup_module is called when rmmod is used to unload the module */ - -void cleanup_module(void) -{ - tdfx_cleanup(); -} -#endif - #ifndef MODULE -/* tdfx_setup is called by the kernel to parse command-line options passed - * via the boot-loader (e.g., LILO). It calls the insmod option routine, - * drm_parse_drm. - * - * This is not currently supported, since it requires changes to - * linux/init/main.c. */ - +/* tdfx_options is called by the kernel to parse command-line options + * passed via the boot-loader (e.g., LILO). It calls the insmod option + * routine, drm_parse_drm. + */ -void __init tdfx_setup(char *str, int *ints) +static int __init tdfx_options(char *str) { - if (ints[0] != 0) { - DRM_ERROR("Illegal command line format, ignored\n"); - return; - } drm_parse_options(str); + return 1; } + +__setup("tdfx=", tdfx_options); #endif static int tdfx_setup(drm_device_t *dev) @@ -241,7 +223,7 @@ static int tdfx_takedown(drm_device_t *dev) } dev->magiclist[i].head = dev->magiclist[i].tail = NULL; } -#ifdef DRM_AGP +#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) /* Clear AGP information */ if (dev->agp) { drm_agp_mem_t *temp; @@ -254,9 +236,7 @@ static int tdfx_takedown(drm_device_t *dev) drm_free(temp, sizeof(*temp), DRM_MEM_AGPLISTS); temp = temp_next; } - if(dev->agp->acquired) (*drm_agp.release)(); - drm_free(dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS); - dev->agp = NULL; + if (dev->agp->acquired) (*drm_agp.release)(); } #endif /* Clear vma list (only built for debugging) */ @@ -319,7 +299,7 @@ static int tdfx_takedown(drm_device_t *dev) /* tdfx_init is called via init_module at module load time, or via * linux/init/main.c (this is not currently supported). */ -int tdfx_init(void) +static int tdfx_init(void) { int retcode; drm_device_t *dev = &tdfx_device; @@ -343,7 +323,7 @@ int tdfx_init(void) drm_mem_init(); drm_proc_init(dev); -#ifdef DRM_AGP +#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) dev->agp = drm_agp_init(); #endif if((retcode = drm_ctxbitmap_init(dev))) { @@ -367,7 +347,7 @@ int tdfx_init(void) /* tdfx_cleanup is called via cleanup_module at module unload time. */ -void tdfx_cleanup(void) +static void tdfx_cleanup(void) { drm_device_t *dev = &tdfx_device; @@ -381,8 +361,19 @@ void tdfx_cleanup(void) } drm_ctxbitmap_cleanup(dev); tdfx_takedown(dev); +#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) + if (dev->agp) { + drm_agp_uninit(); + drm_free(dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS); + dev->agp = NULL; + } +#endif } +module_init(tdfx_init); +module_exit(tdfx_cleanup); + + int tdfx_version(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { @@ -424,7 +415,9 @@ int tdfx_open(struct inode *inode, struct file *filp) DRM_DEBUG("open_count = %d\n", dev->open_count); if (!(retcode = drm_open_helper(inode, filp, dev))) { - MOD_INC_USE_COUNT; +#if LINUX_VERSION_CODE < 0x020333 + MOD_INC_USE_COUNT; /* Needed before Linux 2.3.51 */ +#endif atomic_inc(&dev->total_open); spin_lock(&dev->count_lock); if (!dev->open_count++) { @@ -439,12 +432,17 @@ int tdfx_open(struct inode *inode, struct file *filp) int tdfx_release(struct inode *inode, struct file *filp) { drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; + drm_device_t *dev; int retcode = 0; + lock_kernel(); + dev = priv->dev; + DRM_DEBUG("open_count = %d\n", dev->open_count); if (!(retcode = drm_release(inode, filp))) { - MOD_DEC_USE_COUNT; +#if LINUX_VERSION_CODE < 0x020333 + MOD_DEC_USE_COUNT; /* Needed before Linux 2.3.51 */ +#endif atomic_inc(&dev->total_close); spin_lock(&dev->count_lock); if (!--dev->open_count) { @@ -453,13 +451,17 @@ int tdfx_release(struct inode *inode, struct file *filp) atomic_read(&dev->ioctl_count), dev->blocked); spin_unlock(&dev->count_lock); + unlock_kernel(); return -EBUSY; } spin_unlock(&dev->count_lock); + unlock_kernel(); return tdfx_takedown(dev); } spin_unlock(&dev->count_lock); } + + unlock_kernel(); return retcode; } @@ -625,19 +627,11 @@ int tdfx_lock(struct inode *inode, struct file *filp, unsigned int cmd, } } -#if 0 - DRM_ERROR("pid = %5d, old counter = %5ld\n", - current->pid, current->counter); -#endif +#if LINUX_VERSION_CODE < 0x020400 if (lock.context != tdfx_res_ctx.handle) { current->counter = 5; current->priority = DEF_PRIORITY/4; } -#if 0 - while (current->counter > 25) - current->counter >>= 1; /* decrease time slice */ - DRM_ERROR("pid = %5d, new counter = %5ld\n", - current->pid, current->counter); #endif DRM_DEBUG("%d %s\n", lock.context, ret ? "interrupted" : "has lock"); @@ -679,19 +673,11 @@ int tdfx_unlock(struct inode *inode, struct file *filp, unsigned int cmd, } } -#if 0 - current->policy |= SCHED_YIELD; - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(1000); -#endif - +#if LINUX_VERSION_CODE < 0x020400 if (lock.context != tdfx_res_ctx.handle) { current->counter = 5; current->priority = DEF_PRIORITY; } -#if 0 - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(10); #endif return 0; diff --git a/linux/tdfx_drv.h b/linux/tdfx_drv.h index 879e6d37..a5cef652 100644 --- a/linux/tdfx_drv.h +++ b/linux/tdfx_drv.h @@ -25,17 +25,16 @@ * DEALINGS IN THE SOFTWARE. * * Authors: - * Rickard E. (Rik) Faith <faith@precisioninsight.com> - * Daryll Strauss <daryll@precisioninsight.com> + * Rickard E. (Rik) Faith <faith@valinux.com> + * Daryll Strauss <daryll@valinux.com> * */ +/* $XFree86$ */ #ifndef _TDFX_DRV_H_ #define _TDFX_DRV_H_ /* tdfx_drv.c */ -extern int tdfx_init(void); -extern void tdfx_cleanup(void); extern int tdfx_version(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); extern int tdfx_open(struct inode *inode, struct file *filp); @@ -28,6 +28,7 @@ * Rickard E. (Rik) Faith <faith@valinux.com> * */ +/* $XFree86$ */ #define __NO_VERSION__ #include "drmP.h" @@ -44,6 +45,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, @@ -77,6 +84,40 @@ struct page *drm_vm_shm_nopage(struct vm_area_struct *vma, int write_access) #endif { +#if LINUX_VERSION_CODE >= 0x020300 + drm_map_t *map = (drm_map_t *)vma->vm_private_data; +#else + drm_map_t *map = (drm_map_t *)vma->vm_pte; +#endif + unsigned long physical; + unsigned long offset; + + if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */ + if (!map) return NOPAGE_OOM; /* Nothing allocated */ + + offset = address - vma->vm_start; + physical = (unsigned long)map->handle + offset; + atomic_inc(&virt_to_page(physical)->count); /* Dec. by kernel */ + + DRM_DEBUG("0x%08lx => 0x%08lx\n", address, physical); +#if LINUX_VERSION_CODE < 0x020317 + return physical; +#else + return virt_to_page(physical); +#endif +} + +#if LINUX_VERSION_CODE < 0x020317 +unsigned long drm_vm_shm_nopage_lock(struct vm_area_struct *vma, + unsigned long address, + int write_access) +#else + /* Return type changed in 2.3.23 */ +struct page *drm_vm_shm_nopage_lock(struct vm_area_struct *vma, + unsigned long address, + int write_access) +#endif +{ drm_file_t *priv = vma->vm_file->private_data; drm_device_t *dev = priv->dev; unsigned long physical; @@ -88,14 +129,14 @@ 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 & (~PAGE_MASK)); - atomic_inc(&mem_map[MAP_NR(physical)].count); /* Dec. by kernel */ + physical = (unsigned long)dev->lock.hw_lock + offset; + 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 +165,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 } @@ -145,7 +186,11 @@ void drm_vm_open(struct vm_area_struct *vma) DRM_DEBUG("0x%08lx,0x%08lx\n", vma->vm_start, vma->vm_end - vma->vm_start); atomic_inc(&dev->vma_count); - MOD_INC_USE_COUNT; +#if LINUX_VERSION_CODE < 0x020333 + /* The map can exist after the fd is closed. */ + MOD_INC_USE_COUNT; /* Needed before Linux 2.3.51 */ +#endif + #if DRM_DEBUG_CODE vma_entry = drm_alloc(sizeof(*vma_entry), DRM_MEM_VMAS); @@ -170,7 +215,9 @@ void drm_vm_close(struct vm_area_struct *vma) DRM_DEBUG("0x%08lx,0x%08lx\n", vma->vm_start, vma->vm_end - vma->vm_start); - MOD_DEC_USE_COUNT; +#if LINUX_VERSION_CODE < 0x020333 + MOD_DEC_USE_COUNT; /* Needed before Linux 2.3.51 */ +#endif atomic_dec(&dev->vma_count); #if DRM_DEBUG_CODE @@ -193,15 +240,22 @@ void drm_vm_close(struct vm_area_struct *vma) int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma) { drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; - drm_device_dma_t *dma = dev->dma; + drm_device_t *dev; + drm_device_dma_t *dma; unsigned long length = vma->vm_end - vma->vm_start; + lock_kernel(); + dev = priv->dev; + dma = dev->dma; DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n", vma->vm_start, vma->vm_end, VM_OFFSET(vma)); /* Length must match exact page count */ - if ((length >> PAGE_SHIFT) != dma->page_count) return -EINVAL; + if (!dma || (length >> PAGE_SHIFT) != dma->page_count) { + unlock_kernel(); + return -EINVAL; + } + unlock_kernel(); vma->vm_ops = &drm_vm_dma_ops; vma->vm_flags |= VM_LOCKED | VM_SHM; /* Don't swap */ @@ -270,6 +324,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 */ } @@ -285,7 +342,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/shared-core/drm.h b/shared-core/drm.h index 5a979e1c..44e2d397 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -31,11 +31,16 @@ * Dec 1999, Richard Henderson <rth@twiddle.net>, move to generic cmpxchg. * */ +/* $XFree86$ */ #ifndef _DRM_H_ #define _DRM_H_ +#if defined(__linux__) #include <asm/ioctl.h> /* For _IO* macros */ +#elif defined(__FreeBSD__) +#include <sys/ioccom.h> +#endif #define DRM_PROC_DEVICES "/proc/devices" #define DRM_PROC_MISC "/proc/misc" @@ -289,7 +294,11 @@ typedef struct drm_agp_info { } drm_agp_info_t; #define DRM_IOCTL_BASE 'd' +#if defined(__linux__) #define DRM_IOCTL_NR(n) _IOC_NR(n) +#elif defined(__FreeBSD__) +#define DRM_IOCTL_NR(n) ((n) & 0xff) +#endif #define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr) #define DRM_IOR(nr,size) _IOR(DRM_IOCTL_BASE,nr,size) #define DRM_IOW(nr,size) _IOW(DRM_IOCTL_BASE,nr,size) diff --git a/shared/drm.h b/shared/drm.h index 5a979e1c..44e2d397 100644 --- a/shared/drm.h +++ b/shared/drm.h @@ -31,11 +31,16 @@ * Dec 1999, Richard Henderson <rth@twiddle.net>, move to generic cmpxchg. * */ +/* $XFree86$ */ #ifndef _DRM_H_ #define _DRM_H_ +#if defined(__linux__) #include <asm/ioctl.h> /* For _IO* macros */ +#elif defined(__FreeBSD__) +#include <sys/ioccom.h> +#endif #define DRM_PROC_DEVICES "/proc/devices" #define DRM_PROC_MISC "/proc/misc" @@ -289,7 +294,11 @@ typedef struct drm_agp_info { } drm_agp_info_t; #define DRM_IOCTL_BASE 'd' +#if defined(__linux__) #define DRM_IOCTL_NR(n) _IOC_NR(n) +#elif defined(__FreeBSD__) +#define DRM_IOCTL_NR(n) ((n) & 0xff) +#endif #define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr) #define DRM_IOR(nr,size) _IOR(DRM_IOCTL_BASE,nr,size) #define DRM_IOW(nr,size) _IOW(DRM_IOCTL_BASE,nr,size) |