summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Hartmann <jhartmann@valinux.com>2000-02-13 18:21:04 +0000
committerJeff Hartmann <jhartmann@valinux.com>2000-02-13 18:21:04 +0000
commit72abcbcf88110f0db8bb8cb7c17a76647fde921a (patch)
tree7bd1f7e689fa91c181f211ad653e149e1a4a7cd9
parent597acf4bb2cb1d9805abfecaeb69e8aa255d53d4 (diff)
Added dma flush ioctl
-rw-r--r--linux-core/i810_dma.c81
-rw-r--r--linux-core/i810_drv.c5
-rw-r--r--linux-core/i810_drv.h5
-rw-r--r--linux/i810_dma.c81
-rw-r--r--linux/i810_drm_public.h2
-rw-r--r--linux/i810_drv.c5
-rw-r--r--linux/i810_drv.h5
7 files changed, 73 insertions, 111 deletions
diff --git a/linux-core/i810_dma.c b/linux-core/i810_dma.c
index b28b2401..da2f1951 100644
--- a/linux-core/i810_dma.c
+++ b/linux-core/i810_dma.c
@@ -609,12 +609,14 @@ static int i810_do_dma(drm_device_t *dev, int locked)
/* Always hold the hardware lock while dispatching.
*/
- if (!locked && !drm_lock_take(&dev->lock.hw_lock->lock,
- DRM_KERNEL_CONTEXT)) {
- atomic_inc(&dma->total_missed_lock);
- clear_bit(0, &dev->dma_flag);
- atomic_dec(&dev_priv->dispatch_lock);
- return -EBUSY;
+ if ( ((!locked) ||
+ (atomic_read(&dev_priv->in_flush) != 1))
+ && !drm_lock_take(&dev->lock.hw_lock->lock,
+ DRM_KERNEL_CONTEXT)) {
+ atomic_inc(&dma->total_missed_lock);
+ clear_bit(0, &dev->dma_flag);
+ atomic_dec(&dev_priv->dispatch_lock);
+ return -EBUSY;
}
dma->next_queue = dev->queuelist[DRM_KERNEL_CONTEXT];
@@ -650,10 +652,11 @@ static int i810_do_dma(drm_device_t *dev, int locked)
atomic_add(buf->used, &dma->total_bytes);
atomic_inc(&dma->total_dmas);
- if (!locked) {
- if (drm_lock_free(dev, &dev->lock.hw_lock->lock,
+ if ((!locked)
+ || (atomic_read(&dev_priv->in_flush) != 1)) {
+ if (drm_lock_free(dev, &dev->lock.hw_lock->lock,
DRM_KERNEL_CONTEXT)) {
- DRM_ERROR("\n");
+ DRM_ERROR("\n");
}
}
@@ -928,46 +931,6 @@ int i810_lock(struct inode *inode, struct file *filp, unsigned int cmd,
if (lock.context < 0) {
return -EINVAL;
}
-
- atomic_inc(&dev_priv->in_flush);
- printk("in_flush : %d\n", atomic_read(&dev_priv->in_flush));
- if(atomic_read(&dev_priv->in_flush) != 1) {
- atomic_dec(&dev_priv->in_flush);
- add_wait_queue(&dev->lock.lock_queue, &entry);
- for (;;) {
- /* Contention */
- atomic_inc(&dev->total_sleeps);
- current->state = TASK_INTERRUPTIBLE;
- current->policy |= SCHED_YIELD;
- atomic_inc(&dev_priv->in_flush);
-
- printk("in_flush_loop : %d\n", atomic_read(&dev_priv->in_flush));
- if(atomic_read(&dev_priv->in_flush) == 1) {
- break;
- }
- atomic_dec(&dev_priv->in_flush);
- printk("Calling lock schedule\n");
- schedule();
- if (signal_pending(current)) {
- ret = -ERESTARTSYS;
- break;
- }
- }
- current->state = TASK_RUNNING;
- remove_wait_queue(&dev->lock.lock_queue, &entry);
- }
-
- if (lock.flags & _DRM_LOCK_QUIESCENT) {
- ret = i810_flush_queue(dev);
- if(ret != 0) {
- atomic_dec(&dev_priv->in_flush);
- wake_up_interruptible(&dev->lock.lock_queue);
- }
- } else if (ret == 0) {
- atomic_dec(&dev_priv->in_flush);
- wake_up_interruptible(&dev->lock.lock_queue);
- }
-
/* Only one queue:
*/
@@ -1005,11 +968,27 @@ int i810_lock(struct inode *inode, struct file *filp, unsigned int cmd,
if (!ret) {
if (lock.flags & _DRM_LOCK_QUIESCENT) {
printk("_DRM_LOCK_QUIESCENT\n");
+ atomic_set(&dev_priv->in_flush, 1);
+ i810_flush_queue(dev);
i810_dma_quiescent(dev);
- atomic_dec(&dev_priv->in_flush);
- wake_up_interruptible(&dev->lock.lock_queue);
+ atomic_set(&dev_priv->in_flush, 0);
}
}
printk("%d %s\n", lock.context, ret ? "interrupted" : "has lock");
return ret;
}
+
+int i810_flush_ioctl(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private;
+
+ printk("i810_flush_ioctl\n");
+ atomic_set(&dev_priv->in_flush, 1);
+ i810_flush_queue(dev);
+ i810_dma_quiescent(dev);
+ atomic_set(&dev_priv->in_flush, 0);
+ return 0;
+}
diff --git a/linux-core/i810_drv.c b/linux-core/i810_drv.c
index 9c8531ed..49a3c995 100644
--- a/linux-core/i810_drv.c
+++ b/linux-core/i810_drv.c
@@ -108,8 +108,9 @@ static drm_ioctl_desc_t i810_ioctls[] = {
[DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = { drm_agp_bind, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = { drm_agp_unbind, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_I810_INIT)] = { i810_dma_init, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_I810_VERTEX)] = { i810_dma_vertex, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_I810_DMA)] = { i810_dma_general, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_I810_VERTEX)] = { i810_dma_vertex, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_I810_DMA)] = { i810_dma_general,1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_I810_FLUSH)] = { i810_flush_ioctl,1, 0 },
};
#define I810_IOCTL_COUNT DRM_ARRAY_SIZE(i810_ioctls)
diff --git a/linux-core/i810_drv.h b/linux-core/i810_drv.h
index d0e7ddd7..2cbcc061 100644
--- a/linux-core/i810_drv.h
+++ b/linux-core/i810_drv.h
@@ -83,8 +83,9 @@ extern int i810_control(struct inode *inode, struct file *filp,
extern int i810_lock(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int i810_dma_init(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-
+ unsigned int cmd, unsigned long arg);
+extern int i810_flush_ioctl(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
/* i810_bufs.c */
extern int i810_addbufs(struct inode *inode, struct file *filp,
diff --git a/linux/i810_dma.c b/linux/i810_dma.c
index b28b2401..da2f1951 100644
--- a/linux/i810_dma.c
+++ b/linux/i810_dma.c
@@ -609,12 +609,14 @@ static int i810_do_dma(drm_device_t *dev, int locked)
/* Always hold the hardware lock while dispatching.
*/
- if (!locked && !drm_lock_take(&dev->lock.hw_lock->lock,
- DRM_KERNEL_CONTEXT)) {
- atomic_inc(&dma->total_missed_lock);
- clear_bit(0, &dev->dma_flag);
- atomic_dec(&dev_priv->dispatch_lock);
- return -EBUSY;
+ if ( ((!locked) ||
+ (atomic_read(&dev_priv->in_flush) != 1))
+ && !drm_lock_take(&dev->lock.hw_lock->lock,
+ DRM_KERNEL_CONTEXT)) {
+ atomic_inc(&dma->total_missed_lock);
+ clear_bit(0, &dev->dma_flag);
+ atomic_dec(&dev_priv->dispatch_lock);
+ return -EBUSY;
}
dma->next_queue = dev->queuelist[DRM_KERNEL_CONTEXT];
@@ -650,10 +652,11 @@ static int i810_do_dma(drm_device_t *dev, int locked)
atomic_add(buf->used, &dma->total_bytes);
atomic_inc(&dma->total_dmas);
- if (!locked) {
- if (drm_lock_free(dev, &dev->lock.hw_lock->lock,
+ if ((!locked)
+ || (atomic_read(&dev_priv->in_flush) != 1)) {
+ if (drm_lock_free(dev, &dev->lock.hw_lock->lock,
DRM_KERNEL_CONTEXT)) {
- DRM_ERROR("\n");
+ DRM_ERROR("\n");
}
}
@@ -928,46 +931,6 @@ int i810_lock(struct inode *inode, struct file *filp, unsigned int cmd,
if (lock.context < 0) {
return -EINVAL;
}
-
- atomic_inc(&dev_priv->in_flush);
- printk("in_flush : %d\n", atomic_read(&dev_priv->in_flush));
- if(atomic_read(&dev_priv->in_flush) != 1) {
- atomic_dec(&dev_priv->in_flush);
- add_wait_queue(&dev->lock.lock_queue, &entry);
- for (;;) {
- /* Contention */
- atomic_inc(&dev->total_sleeps);
- current->state = TASK_INTERRUPTIBLE;
- current->policy |= SCHED_YIELD;
- atomic_inc(&dev_priv->in_flush);
-
- printk("in_flush_loop : %d\n", atomic_read(&dev_priv->in_flush));
- if(atomic_read(&dev_priv->in_flush) == 1) {
- break;
- }
- atomic_dec(&dev_priv->in_flush);
- printk("Calling lock schedule\n");
- schedule();
- if (signal_pending(current)) {
- ret = -ERESTARTSYS;
- break;
- }
- }
- current->state = TASK_RUNNING;
- remove_wait_queue(&dev->lock.lock_queue, &entry);
- }
-
- if (lock.flags & _DRM_LOCK_QUIESCENT) {
- ret = i810_flush_queue(dev);
- if(ret != 0) {
- atomic_dec(&dev_priv->in_flush);
- wake_up_interruptible(&dev->lock.lock_queue);
- }
- } else if (ret == 0) {
- atomic_dec(&dev_priv->in_flush);
- wake_up_interruptible(&dev->lock.lock_queue);
- }
-
/* Only one queue:
*/
@@ -1005,11 +968,27 @@ int i810_lock(struct inode *inode, struct file *filp, unsigned int cmd,
if (!ret) {
if (lock.flags & _DRM_LOCK_QUIESCENT) {
printk("_DRM_LOCK_QUIESCENT\n");
+ atomic_set(&dev_priv->in_flush, 1);
+ i810_flush_queue(dev);
i810_dma_quiescent(dev);
- atomic_dec(&dev_priv->in_flush);
- wake_up_interruptible(&dev->lock.lock_queue);
+ atomic_set(&dev_priv->in_flush, 0);
}
}
printk("%d %s\n", lock.context, ret ? "interrupted" : "has lock");
return ret;
}
+
+int i810_flush_ioctl(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private;
+
+ printk("i810_flush_ioctl\n");
+ atomic_set(&dev_priv->in_flush, 1);
+ i810_flush_queue(dev);
+ i810_dma_quiescent(dev);
+ atomic_set(&dev_priv->in_flush, 0);
+ return 0;
+}
diff --git a/linux/i810_drm_public.h b/linux/i810_drm_public.h
index a9577e14..5737c9ff 100644
--- a/linux/i810_drm_public.h
+++ b/linux/i810_drm_public.h
@@ -129,5 +129,5 @@ typedef struct {
#define DRM_IOCTL_I810_INIT DRM_IOW( 0x40, drm_i810_init_t)
#define DRM_IOCTL_I810_VERTEX DRM_IOW( 0x41, drm_i810_vertex_t)
#define DRM_IOCTL_I810_DMA DRM_IOW( 0x42, drm_i810_general_t)
-
+#define DRM_IOCTL_I810_FLUSH DRM_IO ( 0x43)
#endif /* _I810_DRM_H_ */
diff --git a/linux/i810_drv.c b/linux/i810_drv.c
index 9c8531ed..49a3c995 100644
--- a/linux/i810_drv.c
+++ b/linux/i810_drv.c
@@ -108,8 +108,9 @@ static drm_ioctl_desc_t i810_ioctls[] = {
[DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = { drm_agp_bind, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = { drm_agp_unbind, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_I810_INIT)] = { i810_dma_init, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_I810_VERTEX)] = { i810_dma_vertex, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_I810_DMA)] = { i810_dma_general, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_I810_VERTEX)] = { i810_dma_vertex, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_I810_DMA)] = { i810_dma_general,1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_I810_FLUSH)] = { i810_flush_ioctl,1, 0 },
};
#define I810_IOCTL_COUNT DRM_ARRAY_SIZE(i810_ioctls)
diff --git a/linux/i810_drv.h b/linux/i810_drv.h
index d0e7ddd7..2cbcc061 100644
--- a/linux/i810_drv.h
+++ b/linux/i810_drv.h
@@ -83,8 +83,9 @@ extern int i810_control(struct inode *inode, struct file *filp,
extern int i810_lock(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int i810_dma_init(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-
+ unsigned int cmd, unsigned long arg);
+extern int i810_flush_ioctl(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
/* i810_bufs.c */
extern int i810_addbufs(struct inode *inode, struct file *filp,