Added dma flush ioctl

This commit is contained in:
Jeff Hartmann 2000-02-13 18:21:04 +00:00
parent 597acf4bb2
commit 72abcbcf88
7 changed files with 73 additions and 111 deletions

View file

@ -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;
}

View file

@ -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)

View file

@ -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,

View file

@ -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;
}

View file

@ -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_ */

View file

@ -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)

View file

@ -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,