summaryrefslogtreecommitdiff
path: root/linux/mga_dma.c
diff options
context:
space:
mode:
Diffstat (limited to 'linux/mga_dma.c')
-rw-r--r--linux/mga_dma.c26
1 files changed, 15 insertions, 11 deletions
diff --git a/linux/mga_dma.c b/linux/mga_dma.c
index 25e3622c..28e8811c 100644
--- a/linux/mga_dma.c
+++ b/linux/mga_dma.c
@@ -572,10 +572,12 @@ int mga_dma_schedule(drm_device_t *dev, int locked)
{
drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
drm_device_dma_t *dma = dev->dma;
+ int retval = 0;
if (test_and_set_bit(0, &dev->dma_flag)) {
atomic_inc(&dma->total_missed_dma);
- return -EBUSY;
+ retval = -EBUSY;
+ goto sch_out_wakeup;
}
DRM_DEBUG("%s\n", __FUNCTION__);
@@ -591,7 +593,8 @@ int mga_dma_schedule(drm_device_t *dev, int locked)
atomic_inc(&dma->total_missed_lock);
clear_bit(0, &dev->dma_flag);
DRM_DEBUG("Not locked\n");
- return -EBUSY;
+ retval = -EBUSY;
+ goto sch_out_wakeup;
}
DRM_DEBUG("I'm locked\n");
@@ -621,12 +624,12 @@ int mga_dma_schedule(drm_device_t *dev, int locked)
}
}
+sch_out_wakeup:
if(test_bit(MGA_IN_FLUSH, &dev_priv->dispatch_status) &&
- dev_priv->next_prim->num_dwords == 0 &&
atomic_read(&dev_priv->pending_bufs) == 0) {
- /* Everything has been processed by the hardware */
+ /* Everything has been processed by the hardware */
clear_bit(MGA_IN_FLUSH, &dev_priv->dispatch_status);
- wake_up_interruptible(&dev_priv->flush_queue);
+ wake_up_interruptible(&dev_priv->flush_queue);
}
if(test_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status) &&
@@ -641,7 +644,7 @@ int mga_dma_schedule(drm_device_t *dev, int locked)
}
clear_bit(0, &dev->dma_flag);
- return 0;
+ return retval;
}
static void mga_dma_service(int irq, void *device, struct pt_regs *regs)
@@ -956,11 +959,11 @@ static int mga_flush_queue(drm_device_t *dev)
}
if(dev_priv->next_prim->num_dwords != 0) {
- set_bit(MGA_IN_FLUSH, &dev_priv->dispatch_status);
current->state = TASK_INTERRUPTIBLE;
add_wait_queue(&dev_priv->flush_queue, &entry);
+ set_bit(MGA_IN_FLUSH, &dev_priv->dispatch_status);
+ mga_dma_schedule(dev, 0);
for (;;) {
- mga_dma_schedule(dev, 0);
if (!test_bit(MGA_IN_FLUSH,
&dev_priv->dispatch_status))
break;
@@ -1093,14 +1096,15 @@ int mga_flush_ioctl(struct inode *inode, struct file *filp,
}
if(lock.flags & _DRM_LOCK_FLUSH || lock.flags & _DRM_LOCK_FLUSH_ALL) {
- drm_mga_prim_buf_t *temp_buf =
- dev_priv->prim_bufs[dev_priv->current_prim_idx];
+ drm_mga_prim_buf_t *temp_buf;
+
+ temp_buf = dev_priv->current_prim;
if(temp_buf && temp_buf->num_dwords) {
set_bit(MGA_BUF_FORCE_FIRE, &temp_buf->buffer_status);
mga_advance_primary(dev);
- mga_dma_schedule(dev, 1);
}
+ mga_dma_schedule(dev, 1);
}
if(lock.flags & _DRM_LOCK_QUIESCENT) {
mga_flush_queue(dev);