summaryrefslogtreecommitdiff
path: root/linux
diff options
context:
space:
mode:
authorRik Faith <faith@alephnull.com>2000-08-26 10:36:44 +0000
committerRik Faith <faith@alephnull.com>2000-08-26 10:36:44 +0000
commit6f07e1ff6bec8f306e8aa1d59b8bcaa93ffa776e (patch)
tree334961bb4f9cc7c83b95a17d6d79f3bf351bbacf /linux
parent37643234affb329775d3330eed650dee59d39bad (diff)
Sync with Linux 2.4.0-test7 Add signal blocking support to all drivers
(using control-z on a running direct-rendering client should work now)
Diffstat (limited to 'linux')
-rw-r--r--linux/drmP.h10
-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/lock.c32
-rw-r--r--linux/mga_dma.c10
-rw-r--r--linux/mga_drv.c3
-rw-r--r--linux/r128_drv.c13
-rw-r--r--linux/sis_drv.c15
-rw-r--r--linux/tdfx_drv.c13
11 files changed, 120 insertions, 2 deletions
diff --git a/linux/drmP.h b/linux/drmP.h
index aa9bc01a..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
@@ -451,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 */
@@ -535,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;
@@ -729,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/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 9ca72296..d315954d 100644
--- a/linux/mga_dma.c
+++ b/linux/mga_dma.c
@@ -1074,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/r128_drv.c b/linux/r128_drv.c
index fac88247..c4eb634d 100644
--- a/linux/r128_drv.c
+++ b/linux/r128_drv.c
@@ -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_drv.c b/linux/sis_drv.c
index 5dda149a..434a1ccd 100644
--- a/linux/sis_drv.c
+++ b/linux/sis_drv.c
@@ -626,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 */
}
@@ -676,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/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;
}