diff options
author | Jeff Hartmann <jhartmann@valinux.com> | 2000-02-13 18:21:04 +0000 |
---|---|---|
committer | Jeff Hartmann <jhartmann@valinux.com> | 2000-02-13 18:21:04 +0000 |
commit | 72abcbcf88110f0db8bb8cb7c17a76647fde921a (patch) | |
tree | 7bd1f7e689fa91c181f211ad653e149e1a4a7cd9 | |
parent | 597acf4bb2cb1d9805abfecaeb69e8aa255d53d4 (diff) |
Added dma flush ioctl
-rw-r--r-- | linux-core/i810_dma.c | 81 | ||||
-rw-r--r-- | linux-core/i810_drv.c | 5 | ||||
-rw-r--r-- | linux-core/i810_drv.h | 5 | ||||
-rw-r--r-- | linux/i810_dma.c | 81 | ||||
-rw-r--r-- | linux/i810_drm_public.h | 2 | ||||
-rw-r--r-- | linux/i810_drv.c | 5 | ||||
-rw-r--r-- | linux/i810_drv.h | 5 |
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, |