diff options
-rw-r--r-- | linux-core/drmP.h | 11 | ||||
-rw-r--r-- | linux-core/i810_dma.c | 10 | ||||
-rw-r--r-- | linux-core/i810_drv.c | 3 | ||||
-rw-r--r-- | linux-core/mga_drv.c | 3 | ||||
-rw-r--r-- | linux-core/r128_drv.c | 19 | ||||
-rw-r--r-- | linux-core/sis_drv.c | 22 | ||||
-rw-r--r-- | linux-core/tdfx_drv.c | 13 | ||||
-rw-r--r-- | linux/Makefile.linux | 24 | ||||
-rw-r--r-- | linux/drmP.h | 11 | ||||
-rw-r--r-- | linux/gamma_dma.c | 10 | ||||
-rw-r--r-- | linux/gamma_drv.c | 3 | ||||
-rw-r--r-- | linux/i810_dma.c | 10 | ||||
-rw-r--r-- | linux/i810_drv.c | 3 | ||||
-rw-r--r-- | linux/lists.c | 41 | ||||
-rw-r--r-- | linux/lock.c | 32 | ||||
-rw-r--r-- | linux/mga_dma.c | 16 | ||||
-rw-r--r-- | linux/mga_drv.c | 3 | ||||
-rw-r--r-- | linux/mga_drv.h | 38 | ||||
-rw-r--r-- | linux/mga_state.c | 63 | ||||
-rw-r--r-- | linux/picker.c | 5 | ||||
-rw-r--r-- | linux/r128_dma.c | 8 | ||||
-rw-r--r-- | linux/r128_drv.c | 19 | ||||
-rw-r--r-- | linux/sis_drm.h (renamed from linux/sis_drm_public.h) | 0 | ||||
-rw-r--r-- | linux/sis_drv.c | 22 | ||||
-rw-r--r-- | linux/sis_drv.h | 5 | ||||
-rw-r--r-- | linux/sis_mm.c | 2 | ||||
-rw-r--r-- | linux/tdfx_drv.c | 13 |
27 files changed, 310 insertions, 99 deletions
diff --git a/linux-core/drmP.h b/linux-core/drmP.h index 0fa20571..b9a4dab4 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -57,7 +57,7 @@ #include <linux/types.h> #include <linux/agp_backend.h> #endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0) +#if LINUX_VERSION_CODE >= 0x020100 /* KERNEL_VERSION(2,1,0) */ #include <linux/tqueue.h> #include <linux/poll.h> #endif @@ -328,6 +328,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 { @@ -450,6 +451,11 @@ typedef struct { extern drm_agp_func_t drm_agp; #endif +typedef struct drm_sigdata { + int context; + drm_hw_lock_t *lock; +} drm_sigdata_t; + typedef struct drm_device { const char *name; /* Simple driver name */ char *unique; /* Unique identifier: e.g., busid */ @@ -534,6 +540,8 @@ typedef struct drm_device { #endif unsigned long *ctx_bitmap; void *dev_private; + drm_sigdata_t sigdata; /* For block_all_signals */ + sigset_t sigmask; } drm_device_t; @@ -728,6 +736,7 @@ extern int drm_flush_unblock(drm_device_t *dev, int context, drm_lock_flags_t flags); extern int drm_flush_block_and_flush(drm_device_t *dev, int context, drm_lock_flags_t flags); +extern int drm_notifier(void *priv); /* Context Bitmap support (ctxbitmap.c) */ extern int drm_ctxbitmap_init(drm_device_t *dev); diff --git a/linux-core/i810_dma.c b/linux-core/i810_dma.c index 19b7bd92..5792bf39 100644 --- a/linux-core/i810_dma.c +++ b/linux-core/i810_dma.c @@ -1227,6 +1227,16 @@ int i810_lock(struct inode *inode, struct file *filp, unsigned int cmd, } if (!ret) { +#if LINUX_VERSION_CODE >= 0x020400 /* KERNEL_VERSION(2,4,0) */ + sigemptyset(&dev->sigmask); + sigaddset(&dev->sigmask, SIGSTOP); + sigaddset(&dev->sigmask, SIGTSTP); + sigaddset(&dev->sigmask, SIGTTIN); + sigaddset(&dev->sigmask, SIGTTOU); + dev->sigdata.context = lock.context; + dev->sigdata.lock = dev->lock.hw_lock; + block_all_signals(drm_notifier, &dev->sigdata, &dev->sigmask); +#endif if (lock.flags & _DRM_LOCK_QUIESCENT) { DRM_DEBUG("_DRM_LOCK_QUIESCENT\n"); DRM_DEBUG("fred\n"); diff --git a/linux-core/i810_drv.c b/linux-core/i810_drv.c index 275663a1..18168605 100644 --- a/linux-core/i810_drv.c +++ b/linux-core/i810_drv.c @@ -642,5 +642,8 @@ int i810_unlock(struct inode *inode, struct file *filp, unsigned int cmd, - dev->lck_start)]); #endif +#if LINUX_VERSION_CODE >= 0x020400 /* KERNEL_VERSION(2,4,0) */ + unblock_all_signals(); +#endif return 0; } diff --git a/linux-core/mga_drv.c b/linux-core/mga_drv.c index acc42b83..a4a8fe55 100644 --- a/linux-core/mga_drv.c +++ b/linux-core/mga_drv.c @@ -655,5 +655,8 @@ int mga_unlock(struct inode *inode, struct file *filp, unsigned int cmd, DRM_ERROR("\n"); } +#if LINUX_VERSION_CODE >= 0x020400 /* KERNEL_VERSION(2,4,0) */ + unblock_all_signals(); +#endif return 0; } diff --git a/linux-core/r128_drv.c b/linux-core/r128_drv.c index fac88247..dd982ab4 100644 --- a/linux-core/r128_drv.c +++ b/linux-core/r128_drv.c @@ -35,7 +35,7 @@ #define R128_NAME "r128" #define R128_DESC "ATI Rage 128" -#define R128_DATE "20000719" +#define R128_DATE "20000827" #define R128_MAJOR 1 #define R128_MINOR 0 #define R128_PATCHLEVEL 0 @@ -466,7 +466,7 @@ int r128_open(struct inode *inode, struct file *filp) } spin_unlock(&dev->count_lock); } - + return retcode; } @@ -500,7 +500,7 @@ int r128_release(struct inode *inode, struct file *filp) } spin_unlock(&dev->count_lock); } - + unlock_kernel(); return retcode; } @@ -656,6 +656,16 @@ int r128_lock(struct inode *inode, struct file *filp, unsigned int cmd, #endif if (!ret) { +#if LINUX_VERSION_CODE >= 0x020400 /* KERNEL_VERSION(2,4,0) */ + sigemptyset(&dev->sigmask); + sigaddset(&dev->sigmask, SIGSTOP); + sigaddset(&dev->sigmask, SIGTSTP); + sigaddset(&dev->sigmask, SIGTTIN); + sigaddset(&dev->sigmask, SIGTTOU); + dev->sigdata.context = lock.context; + dev->sigdata.lock = dev->lock.hw_lock; + block_all_signals(drm_notifier, &dev->sigdata, &dev->sigmask); +#endif if (lock.flags & _DRM_LOCK_READY) { /* Wait for space in DMA/FIFO */ } @@ -720,5 +730,8 @@ int r128_unlock(struct inode *inode, struct file *filp, unsigned int cmd, } #endif +#if LINUX_VERSION_CODE >= 0x020400 /* KERNEL_VERSION(2,4,0) */ + unblock_all_signals(); +#endif return 0; } diff --git a/linux-core/sis_drv.c b/linux-core/sis_drv.c index c04561ee..434a1ccd 100644 --- a/linux-core/sis_drv.c +++ b/linux-core/sis_drv.c @@ -1,5 +1,4 @@ /* sis.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. * All Rights Reserved. @@ -23,15 +22,11 @@ * 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> - * */ #include <linux/config.h> #include "drmP.h" -#include "sis_drm_public.h" +#include "sis_drm.h" #include "sis_drv.h" #define SIS_NAME "sis" @@ -631,6 +626,16 @@ int sis_lock(struct inode *inode, struct file *filp, unsigned int cmd, #endif if (!ret) { +#if LINUX_VERSION_CODE >= 0x020400 /* KERNEL_VERSION(2,4,0) */ + sigemptyset(&dev->sigmask); + sigaddset(&dev->sigmask, SIGSTOP); + sigaddset(&dev->sigmask, SIGTSTP); + sigaddset(&dev->sigmask, SIGTTIN); + sigaddset(&dev->sigmask, SIGTTOU); + dev->sigdata.context = lock.context; + dev->sigdata.lock = dev->lock.hw_lock; + block_all_signals(drm_notifier, &dev->sigdata, &dev->sigmask); +#endif if (lock.flags & _DRM_LOCK_READY) { /* Wait for space in DMA/FIFO */ } @@ -681,7 +686,10 @@ int sis_unlock(struct inode *inode, struct file *filp, unsigned int cmd, DRM_ERROR("\n"); } } - + +#if LINUX_VERSION_CODE >= 0x020400 /* KERNEL_VERSION(2,4,0) */ + unblock_all_signals(); +#endif return 0; } diff --git a/linux-core/tdfx_drv.c b/linux-core/tdfx_drv.c index 59f10197..07febea1 100644 --- a/linux-core/tdfx_drv.c +++ b/linux-core/tdfx_drv.c @@ -615,6 +615,16 @@ int tdfx_lock(struct inode *inode, struct file *filp, unsigned int cmd, #endif if (!ret) { +#if LINUX_VERSION_CODE >= 0x020400 /* KERNEL_VERSION(2,4,0) */ + sigemptyset(&dev->sigmask); + sigaddset(&dev->sigmask, SIGSTOP); + sigaddset(&dev->sigmask, SIGTSTP); + sigaddset(&dev->sigmask, SIGTTIN); + sigaddset(&dev->sigmask, SIGTTOU); + dev->sigdata.context = lock.context; + dev->sigdata.lock = dev->lock.hw_lock; + block_all_signals(drm_notifier, &dev->sigdata, &dev->sigmask); +#endif if (lock.flags & _DRM_LOCK_READY) { /* Wait for space in DMA/FIFO */ } @@ -679,5 +689,8 @@ int tdfx_unlock(struct inode *inode, struct file *filp, unsigned int cmd, } #endif +#if LINUX_VERSION_CODE >= 0x020400 /* KERNEL_VERSION(2,4,0) */ + unblock_all_signals(); +#endif return 0; } diff --git a/linux/Makefile.linux b/linux/Makefile.linux index fd136e97..7dfb20b1 100644 --- a/linux/Makefile.linux +++ b/linux/Makefile.linux @@ -48,7 +48,7 @@ # **** End of SMP/MODVERSIONS detection -MODS= gamma.o tdfx.o r128.o sis.o +MODS= gamma.o tdfx.o r128.o LIBS= libdrm.a PROGS= drmstat @@ -65,9 +65,6 @@ TDFXHEADERS= tdfx_drv.h $(DRMHEADERS) R128OBJS= r128_drv.o r128_dma.o r128_bufs.o r128_context.o R128HEADERS= r128_drv.h r128_drm.h $(DRMHEADERS) -SISOBJS= sis_drv.o sis_context.o sis_ds.o sis_mm.o -SISHEADERS= sis_drv.h sis_ds.h sis_drm_public.h $(DRMHEADERS) - PROGOBJS= drmstat.po xf86drm.po xf86drmHash.po xf86drmRandom.po sigio.po PROGHEADERS= xf86drm.h $(DRMHEADERS) @@ -125,8 +122,10 @@ MODVERSIONS := $(shell gcc -E -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) +SIS := $(shell gcc -E -nostdinc -I$(TREE) picker.c 2>/dev/null \ + | grep -s 'SIS = ' | cut -d' ' -f3) PARAMS := $(shell if fgrep kill_fasync $(TREE)/linux/fs.h \ - | fgrep -q band; then echo 3; else echo 2; fi) + | egrep -q '(band|int, int)'; then echo 3; else echo 2; fi) ifeq ($(AGP),0) AGP := $(shell gcc -E -nostdinc -I$(TREE) picker.c 2>/dev/null \ | grep -s 'AGP_MODULE = ' | cut -d' ' -f3) @@ -144,8 +143,21 @@ I810OBJS= i810_drv.o i810_dma.o i810_bufs.o i810_context.o I810HEADERS= i810_drv.h $(DRMHEADERS) endif +ifeq ($(SIS),1) +# It appears that the SiS driver makes calls to sis_malloc and sis_free, and +# that these calls are only defined if CONFIG_FB_SIS is selected. So, key +# off that to determine if we should attempt to build the SiS driver. +# +# A better way would be to detect the appropriate definitions in the header +# file to see if we can, at least, compile the driver. +MODS += sis.o + +SISOBJS= sis_drv.o sis_context.o sis_ds.o sis_mm.o +SISHEADERS= sis_drv.h sis_ds.h sis_drm.h $(DRMHEADERS) +endif + all::;@echo === KERNEL HEADERS IN $(TREE) -all::;@echo === SMP=${SMP} MODVERSIONS=${MODVERSIONS} AGP=${AGP} +all::;@echo === SMP=${SMP} MODVERSIONS=${MODVERSIONS} AGP=${AGP} SIS=${SIS} all::;@echo === kill_fasync has $(PARAMS) parameters all:: $(LIBS) $(MODS) $(PROGS) endif diff --git a/linux/drmP.h b/linux/drmP.h index 0fa20571..b9a4dab4 100644 --- a/linux/drmP.h +++ b/linux/drmP.h @@ -57,7 +57,7 @@ #include <linux/types.h> #include <linux/agp_backend.h> #endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0) +#if LINUX_VERSION_CODE >= 0x020100 /* KERNEL_VERSION(2,1,0) */ #include <linux/tqueue.h> #include <linux/poll.h> #endif @@ -328,6 +328,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 { @@ -450,6 +451,11 @@ typedef struct { extern drm_agp_func_t drm_agp; #endif +typedef struct drm_sigdata { + int context; + drm_hw_lock_t *lock; +} drm_sigdata_t; + typedef struct drm_device { const char *name; /* Simple driver name */ char *unique; /* Unique identifier: e.g., busid */ @@ -534,6 +540,8 @@ typedef struct drm_device { #endif unsigned long *ctx_bitmap; void *dev_private; + drm_sigdata_t sigdata; /* For block_all_signals */ + sigset_t sigmask; } drm_device_t; @@ -728,6 +736,7 @@ extern int drm_flush_unblock(drm_device_t *dev, int context, drm_lock_flags_t flags); extern int drm_flush_block_and_flush(drm_device_t *dev, int context, drm_lock_flags_t flags); +extern int drm_notifier(void *priv); /* Context Bitmap support (ctxbitmap.c) */ extern int drm_ctxbitmap_init(drm_device_t *dev); diff --git a/linux/gamma_dma.c b/linux/gamma_dma.c index a99f24ca..4a2acfb3 100644 --- a/linux/gamma_dma.c +++ b/linux/gamma_dma.c @@ -804,6 +804,16 @@ int gamma_lock(struct inode *inode, struct file *filp, unsigned int cmd, drm_flush_unblock(dev, lock.context, lock.flags); /* cleanup phase */ if (!ret) { +#if LINUX_VERSION_CODE >= 0x020400 /* KERNEL_VERSION(2,4,0) */ + sigemptyset(&dev->sigmask); + sigaddset(&dev->sigmask, SIGSTOP); + sigaddset(&dev->sigmask, SIGTSTP); + sigaddset(&dev->sigmask, SIGTTIN); + sigaddset(&dev->sigmask, SIGTTOU); + dev->sigdata.context = lock.context; + dev->sigdata.lock = dev->lock.hw_lock; + block_all_signals(drm_notifier, &dev->sigdata, &dev->sigmask); +#endif if (lock.flags & _DRM_LOCK_READY) gamma_dma_ready(dev); if (lock.flags & _DRM_LOCK_QUIESCENT) { diff --git a/linux/gamma_drv.c b/linux/gamma_drv.c index 13d37c24..1fcd1933 100644 --- a/linux/gamma_drv.c +++ b/linux/gamma_drv.c @@ -564,5 +564,8 @@ int gamma_unlock(struct inode *inode, struct file *filp, unsigned int cmd, - dev->lck_start)]); #endif +#if LINUX_VERSION_CODE >= 0x020400 /* KERNEL_VERSION(2,4,0) */ + unblock_all_signals(); +#endif return 0; } diff --git a/linux/i810_dma.c b/linux/i810_dma.c index 19b7bd92..5792bf39 100644 --- a/linux/i810_dma.c +++ b/linux/i810_dma.c @@ -1227,6 +1227,16 @@ int i810_lock(struct inode *inode, struct file *filp, unsigned int cmd, } if (!ret) { +#if LINUX_VERSION_CODE >= 0x020400 /* KERNEL_VERSION(2,4,0) */ + sigemptyset(&dev->sigmask); + sigaddset(&dev->sigmask, SIGSTOP); + sigaddset(&dev->sigmask, SIGTSTP); + sigaddset(&dev->sigmask, SIGTTIN); + sigaddset(&dev->sigmask, SIGTTOU); + dev->sigdata.context = lock.context; + dev->sigdata.lock = dev->lock.hw_lock; + block_all_signals(drm_notifier, &dev->sigdata, &dev->sigmask); +#endif if (lock.flags & _DRM_LOCK_QUIESCENT) { DRM_DEBUG("_DRM_LOCK_QUIESCENT\n"); DRM_DEBUG("fred\n"); diff --git a/linux/i810_drv.c b/linux/i810_drv.c index 275663a1..18168605 100644 --- a/linux/i810_drv.c +++ b/linux/i810_drv.c @@ -642,5 +642,8 @@ int i810_unlock(struct inode *inode, struct file *filp, unsigned int cmd, - dev->lck_start)]); #endif +#if LINUX_VERSION_CODE >= 0x020400 /* KERNEL_VERSION(2,4,0) */ + unblock_all_signals(); +#endif return 0; } diff --git a/linux/lists.c b/linux/lists.c index f62495aa..5da7cc6c 100644 --- a/linux/lists.c +++ b/linux/lists.c @@ -116,6 +116,7 @@ int drm_freelist_create(drm_freelist_t *bl, int count) bl->low_mark = 0; bl->high_mark = 0; atomic_set(&bl->wfh, 0); + bl->lock = SPIN_LOCK_UNLOCKED; ++bl->initialized; return 0; } @@ -130,8 +131,6 @@ int drm_freelist_destroy(drm_freelist_t *bl) int drm_freelist_put(drm_device_t *dev, drm_freelist_t *bl, drm_buf_t *buf) { - drm_buf_t *old, *prev; - int count = 0; drm_device_dma_t *dma = dev->dma; if (!dma) { @@ -152,15 +151,12 @@ int drm_freelist_put(drm_device_t *dev, drm_freelist_t *bl, drm_buf_t *buf) drm_histogram_compute(dev, buf); #endif buf->list = DRM_LIST_FREE; - do { - old = bl->next; - buf->next = old; - prev = cmpxchg(&bl->next, old, buf); - if (++count > DRM_LOOPING_LIMIT) { - DRM_ERROR("Looping\n"); - return 1; - } - } while (prev != old); + + spin_lock(&bl->lock); + buf->next = bl->next; + bl->next = buf; + spin_unlock(&bl->lock); + atomic_inc(&bl->count); if (atomic_read(&bl->count) > dma->buf_count) { DRM_ERROR("%d of %d buffers free after addition of %d\n", @@ -177,26 +173,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/lock.c b/linux/lock.c index 55082727..33b2cc03 100644 --- a/linux/lock.c +++ b/linux/lock.c @@ -223,3 +223,35 @@ int drm_finish(struct inode *inode, struct file *filp, unsigned int cmd, drm_flush_unblock(dev, lock.context, lock.flags); return ret; } + +/* If we get here, it means that the process has called DRM_IOCTL_LOCK + without calling DRM_IOCTL_UNLOCK. + + If the lock is not held, then let the signal proceed as usual. + + If the lock is held, then set the contended flag and keep the signal + blocked. + + + Return 1 if the signal should be delivered normally. + Return 0 if the signal should be blocked. */ + +int drm_notifier(void *priv) +{ + drm_sigdata_t *s = (drm_sigdata_t *)priv; + unsigned int old, new, prev; + + + /* Allow signal delivery if lock isn't held */ + if (!_DRM_LOCK_IS_HELD(s->lock->lock) + || _DRM_LOCKING_CONTEXT(s->lock->lock) != s->context) return 1; + + /* Otherwise, set flag to force call to + drmUnlock */ + do { + old = s->lock->lock; + new = old | _DRM_LOCK_CONT; + prev = cmpxchg(&s->lock->lock, old, new); + } while (prev != old); + return 0; +} diff --git a/linux/mga_dma.c b/linux/mga_dma.c index 0df0906e..d315954d 100644 --- a/linux/mga_dma.c +++ b/linux/mga_dma.c @@ -82,6 +82,7 @@ static void mga_delay(void) return; } +#ifdef __i386__ void mga_flush_write_combine(void) { int xchangeDummy; @@ -92,6 +93,7 @@ void mga_flush_write_combine(void) " movl $0,%%eax ; cpuid ; pop %%edx ; pop %%ecx ; pop %%ebx ;" " pop %%eax" : /* no outputs */ : /* no inputs */ ); } +#endif /* These are two age tags that will never be sent to * the hardware */ @@ -427,7 +429,9 @@ void mga_fire_primary(drm_device_t *dev, drm_mga_prim_buf_t *prim) } } +#ifdef __i386__ mga_flush_write_combine(); +#endif atomic_inc(&dev_priv->pending_bufs); MGA_WRITE(MGAREG_PRIMADDRESS, phys_head | TT_GENERAL); MGA_WRITE(MGAREG_PRIMEND, (phys_head + num_dwords * 4) | use_agp); @@ -824,7 +828,9 @@ static int mga_dma_initialize(drm_device_t *dev, drm_mga_init_t *init) { * the status register will be correct */ +#ifdef __i386__ mga_flush_write_combine(); +#endif MGA_WRITE(MGAREG_PRIMADDRESS, phys_head | TT_GENERAL); MGA_WRITE(MGAREG_PRIMEND, ((phys_head + num_dwords * 4) | @@ -1068,6 +1074,16 @@ int mga_lock(struct inode *inode, struct file *filp, unsigned int cmd, } if (!ret) { +#if LINUX_VERSION_CODE >= 0x020400 /* KERNEL_VERSION(2,4,0) */ + sigemptyset(&dev->sigmask); + sigaddset(&dev->sigmask, SIGSTOP); + sigaddset(&dev->sigmask, SIGTSTP); + sigaddset(&dev->sigmask, SIGTTIN); + sigaddset(&dev->sigmask, SIGTTOU); + dev->sigdata.context = lock.context; + dev->sigdata.lock = dev->lock.hw_lock; + block_all_signals(drm_notifier, &dev->sigdata, &dev->sigmask); +#endif if (lock.flags & _DRM_LOCK_QUIESCENT) { DRM_DEBUG("_DRM_LOCK_QUIESCENT\n"); mga_flush_queue(dev); diff --git a/linux/mga_drv.c b/linux/mga_drv.c index acc42b83..a4a8fe55 100644 --- a/linux/mga_drv.c +++ b/linux/mga_drv.c @@ -655,5 +655,8 @@ int mga_unlock(struct inode *inode, struct file *filp, unsigned int cmd, DRM_ERROR("\n"); } +#if LINUX_VERSION_CODE >= 0x020400 /* KERNEL_VERSION(2,4,0) */ + unblock_all_signals(); +#endif return 0; } diff --git a/linux/mga_drv.h b/linux/mga_drv.h index fe9e3dbe..f49bd0f6 100644 --- a/linux/mga_drv.h +++ b/linux/mga_drv.h @@ -39,8 +39,8 @@ typedef struct { u32 buffer_status; - unsigned int num_dwords; - unsigned int max_dwords; + int num_dwords; + int max_dwords; u32 *current_dma_ptr; u32 *head; u32 phys_head; @@ -209,19 +209,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..5a9c7632 100644 --- a/linux/mga_state.c +++ b/linux/mga_state.c @@ -34,6 +34,22 @@ #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 +76,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 +240,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 +507,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 +540,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 +555,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 +604,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 +617,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 +667,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 +675,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 +746,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 +761,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 +770,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); @@ -817,7 +820,9 @@ int mga_clear_bufs(struct inode *inode, struct file *filp, mga_dma_dispatch_clear(dev, clear.flags, clear.clear_color, clear.clear_depth); PRIMUPDATE(dev_priv); +#ifdef __i386__ mga_flush_write_combine(); +#endif mga_dma_schedule(dev, 1); return 0; } @@ -847,7 +852,9 @@ int mga_swap_bufs(struct inode *inode, struct file *filp, PRIMUPDATE(dev_priv); set_bit(MGA_BUF_SWAP_PENDING, &dev_priv->current_prim->buffer_status); +#ifdef __i386__ mga_flush_write_combine(); +#endif mga_dma_schedule(dev, 1); return 0; } @@ -895,7 +902,9 @@ int mga_iload(struct inode *inode, struct file *filp, AGEBUF(dev_priv, buf_priv); buf_priv->discard = 1; mga_freelist_put(dev, buf); +#ifdef __i386__ mga_flush_write_combine(); +#endif mga_dma_schedule(dev, 1); return 0; } @@ -943,7 +952,9 @@ int mga_vertex(struct inode *inode, struct file *filp, mga_dma_dispatch_vertex(dev, buf); PRIMUPDATE(dev_priv); +#ifdef __i386__ mga_flush_write_combine(); +#endif mga_dma_schedule(dev, 1); return 0; } @@ -990,7 +1001,9 @@ int mga_indices(struct inode *inode, struct file *filp, mga_dma_dispatch_indices(dev, buf, indices.start, indices.end); PRIMUPDATE(dev_priv); +#ifdef __i386__ mga_flush_write_combine(); +#endif mga_dma_schedule(dev, 1); return 0; } diff --git a/linux/picker.c b/linux/picker.c index 0bd8bfd5..f8cfe459 100644 --- a/linux/picker.c +++ b/linux/picker.c @@ -17,8 +17,13 @@ #define CONFIG_AGP 0 #endif +#ifndef CONFIG_FB_SIS +#define CONFIG_FB_SIS 0 +#endif + SMP = CONFIG_SMP MODVERSIONS = CONFIG_MODVERSIONS AGP = CONFIG_AGP AGP_MODULE = CONFIG_AGP_MODULE RELEASE = UTS_RELEASE +SIS = CONFIG_FB_SIS diff --git a/linux/r128_dma.c b/linux/r128_dma.c index 16f79c1f..d4b75bed 100644 --- a/linux/r128_dma.c +++ b/linux/r128_dma.c @@ -68,6 +68,7 @@ int R128_READ_PLL(drm_device_t *dev, int addr) return R128_READ(R128_CLOCK_CNTL_DATA); } +#ifdef __i386__ static void r128_flush_write_combine(void) { int xchangeDummy; @@ -86,6 +87,7 @@ static void r128_flush_write_combine(void) "pop %%ebx ;" "pop %%eax" : /* no outputs */ : /* no inputs */ ); } +#endif static void r128_status(drm_device_t *dev) { @@ -496,8 +498,10 @@ static int r128_submit_packets_ring_secure(drm_device_t *dev, dev_priv->ring_start, write * sizeof(u32)); +#ifdef __i386__ /* Make sure WC cache has been flushed */ r128_flush_write_combine(); +#endif dev_priv->sarea_priv->ring_write = write; R128_WRITE(R128_PM4_BUFFER_DL_WPTR, write); @@ -599,8 +603,10 @@ static int r128_submit_packets_ring(drm_device_t *dev, dev_priv->ring_start, write * sizeof(u32)); +#ifdef __i386__ /* Make sure WC cache has been flushed */ r128_flush_write_combine(); +#endif dev_priv->sarea_priv->ring_write = write; R128_WRITE(R128_PM4_BUFFER_DL_WPTR, write); @@ -766,8 +772,10 @@ static int r128_send_vertbufs(drm_device_t *dev, drm_r128_vertex_t *v) r128_mark_vertbufs_done(dev); } +#ifdef __i386__ /* Make sure WC cache has been flushed (if in PIO mode) */ if (!dev_priv->cce_is_bm_mode) r128_flush_write_combine(); +#endif /* FIXME: Add support for sending vertex buffer to the CCE here instead of in client code. The v->prim holds the primitive diff --git a/linux/r128_drv.c b/linux/r128_drv.c index fac88247..dd982ab4 100644 --- a/linux/r128_drv.c +++ b/linux/r128_drv.c @@ -35,7 +35,7 @@ #define R128_NAME "r128" #define R128_DESC "ATI Rage 128" -#define R128_DATE "20000719" +#define R128_DATE "20000827" #define R128_MAJOR 1 #define R128_MINOR 0 #define R128_PATCHLEVEL 0 @@ -466,7 +466,7 @@ int r128_open(struct inode *inode, struct file *filp) } spin_unlock(&dev->count_lock); } - + return retcode; } @@ -500,7 +500,7 @@ int r128_release(struct inode *inode, struct file *filp) } spin_unlock(&dev->count_lock); } - + unlock_kernel(); return retcode; } @@ -656,6 +656,16 @@ int r128_lock(struct inode *inode, struct file *filp, unsigned int cmd, #endif if (!ret) { +#if LINUX_VERSION_CODE >= 0x020400 /* KERNEL_VERSION(2,4,0) */ + sigemptyset(&dev->sigmask); + sigaddset(&dev->sigmask, SIGSTOP); + sigaddset(&dev->sigmask, SIGTSTP); + sigaddset(&dev->sigmask, SIGTTIN); + sigaddset(&dev->sigmask, SIGTTOU); + dev->sigdata.context = lock.context; + dev->sigdata.lock = dev->lock.hw_lock; + block_all_signals(drm_notifier, &dev->sigdata, &dev->sigmask); +#endif if (lock.flags & _DRM_LOCK_READY) { /* Wait for space in DMA/FIFO */ } @@ -720,5 +730,8 @@ int r128_unlock(struct inode *inode, struct file *filp, unsigned int cmd, } #endif +#if LINUX_VERSION_CODE >= 0x020400 /* KERNEL_VERSION(2,4,0) */ + unblock_all_signals(); +#endif return 0; } diff --git a/linux/sis_drm_public.h b/linux/sis_drm.h index dd14a5a5..dd14a5a5 100644 --- a/linux/sis_drm_public.h +++ b/linux/sis_drm.h diff --git a/linux/sis_drv.c b/linux/sis_drv.c index c04561ee..434a1ccd 100644 --- a/linux/sis_drv.c +++ b/linux/sis_drv.c @@ -1,5 +1,4 @@ /* sis.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. * All Rights Reserved. @@ -23,15 +22,11 @@ * 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> - * */ #include <linux/config.h> #include "drmP.h" -#include "sis_drm_public.h" +#include "sis_drm.h" #include "sis_drv.h" #define SIS_NAME "sis" @@ -631,6 +626,16 @@ int sis_lock(struct inode *inode, struct file *filp, unsigned int cmd, #endif if (!ret) { +#if LINUX_VERSION_CODE >= 0x020400 /* KERNEL_VERSION(2,4,0) */ + sigemptyset(&dev->sigmask); + sigaddset(&dev->sigmask, SIGSTOP); + sigaddset(&dev->sigmask, SIGTSTP); + sigaddset(&dev->sigmask, SIGTTIN); + sigaddset(&dev->sigmask, SIGTTOU); + dev->sigdata.context = lock.context; + dev->sigdata.lock = dev->lock.hw_lock; + block_all_signals(drm_notifier, &dev->sigdata, &dev->sigmask); +#endif if (lock.flags & _DRM_LOCK_READY) { /* Wait for space in DMA/FIFO */ } @@ -681,7 +686,10 @@ int sis_unlock(struct inode *inode, struct file *filp, unsigned int cmd, DRM_ERROR("\n"); } } - + +#if LINUX_VERSION_CODE >= 0x020400 /* KERNEL_VERSION(2,4,0) */ + unblock_all_signals(); +#endif return 0; } diff --git a/linux/sis_drv.h b/linux/sis_drv.h index 50f6efad..24523b8f 100644 --- a/linux/sis_drv.h +++ b/linux/sis_drv.h @@ -1,5 +1,4 @@ /* sis_drv.h -- Private header for sis driver -*- linux-c -*- - * Created: Thu Oct 7 10:40:04 1999 by faith@precisioninsight.com * * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. * All rights reserved. @@ -23,10 +22,6 @@ * 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> - * */ /* $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 $ */ diff --git a/linux/sis_mm.c b/linux/sis_mm.c index 1d6a2748..333b5196 100644 --- a/linux/sis_mm.c +++ b/linux/sis_mm.c @@ -2,7 +2,7 @@ #define __NO_VERSION__ #include "drmP.h" -#include "sis_drm_public.h" +#include "sis_drm.h" #include "sis_ds.h" #include "sis_drv.h" #include <linux/fb.h> diff --git a/linux/tdfx_drv.c b/linux/tdfx_drv.c index 59f10197..07febea1 100644 --- a/linux/tdfx_drv.c +++ b/linux/tdfx_drv.c @@ -615,6 +615,16 @@ int tdfx_lock(struct inode *inode, struct file *filp, unsigned int cmd, #endif if (!ret) { +#if LINUX_VERSION_CODE >= 0x020400 /* KERNEL_VERSION(2,4,0) */ + sigemptyset(&dev->sigmask); + sigaddset(&dev->sigmask, SIGSTOP); + sigaddset(&dev->sigmask, SIGTSTP); + sigaddset(&dev->sigmask, SIGTTIN); + sigaddset(&dev->sigmask, SIGTTOU); + dev->sigdata.context = lock.context; + dev->sigdata.lock = dev->lock.hw_lock; + block_all_signals(drm_notifier, &dev->sigdata, &dev->sigmask); +#endif if (lock.flags & _DRM_LOCK_READY) { /* Wait for space in DMA/FIFO */ } @@ -679,5 +689,8 @@ int tdfx_unlock(struct inode *inode, struct file *filp, unsigned int cmd, } #endif +#if LINUX_VERSION_CODE >= 0x020400 /* KERNEL_VERSION(2,4,0) */ + unblock_all_signals(); +#endif return 0; } |