summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGareth Hughes <gareth@users.sourceforge.net>2000-08-27 16:55:07 +0000
committerGareth Hughes <gareth@users.sourceforge.net>2000-08-27 16:55:07 +0000
commita5c98c730f6a865f0fb457103bfeb6dad5b82045 (patch)
tree4fa4a25c43b5d58186af35f57f9601e671296963
parentae24dece16ecc9f491f9591379ff7897c9b507a4 (diff)
Get latest kernel module updates from Rik Faith. Thanks, Rik! Sync with
2.4.0-test7, other fixes currently on the trunk.
-rw-r--r--linux-core/drmP.h11
-rw-r--r--linux-core/i810_dma.c10
-rw-r--r--linux-core/i810_drv.c3
-rw-r--r--linux-core/mga_drv.c3
-rw-r--r--linux-core/r128_drv.c19
-rw-r--r--linux-core/sis_drv.c22
-rw-r--r--linux-core/tdfx_drv.c13
-rw-r--r--linux/Makefile.linux24
-rw-r--r--linux/drmP.h11
-rw-r--r--linux/gamma_dma.c10
-rw-r--r--linux/gamma_drv.c3
-rw-r--r--linux/i810_dma.c10
-rw-r--r--linux/i810_drv.c3
-rw-r--r--linux/lists.c41
-rw-r--r--linux/lock.c32
-rw-r--r--linux/mga_dma.c16
-rw-r--r--linux/mga_drv.c3
-rw-r--r--linux/mga_drv.h38
-rw-r--r--linux/mga_state.c63
-rw-r--r--linux/picker.c5
-rw-r--r--linux/r128_dma.c8
-rw-r--r--linux/r128_drv.c19
-rw-r--r--linux/sis_drm.h (renamed from linux/sis_drm_public.h)0
-rw-r--r--linux/sis_drv.c22
-rw-r--r--linux/sis_drv.h5
-rw-r--r--linux/sis_mm.c2
-rw-r--r--linux/tdfx_drv.c13
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;
}