patch-2.4.0-test9 linux/drivers/char/drm/mga_dma.c

Next file: linux/drivers/char/drm/mga_drm.h
Previous file: linux/drivers/char/drm/mga_context.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/char/drm/mga_dma.c linux/drivers/char/drm/mga_dma.c
@@ -11,11 +11,11 @@
  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  * and/or sell copies of the Software, and to permit persons to whom the
  * Software is furnished to do so, subject to the following conditions:
- * 
+ *
  * The above copyright notice and this permission notice (including the next
  * paragraph) shall be included in all copies or substantial portions of the
  * Software.
- * 
+ *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
@@ -51,53 +51,30 @@
 static unsigned long mga_alloc_page(drm_device_t *dev)
 {
 	unsigned long address;
-   
-	DRM_DEBUG("%s\n", __FUNCTION__);
+
 	address = __get_free_page(GFP_KERNEL);
 	if(address == 0UL) {
 		return 0;
 	}
 	atomic_inc(&virt_to_page(address)->count);
-	set_bit(PG_locked, &virt_to_page(address)->flags);
-   
+	set_bit(PG_reserved, &virt_to_page(address)->flags);
+
 	return address;
 }
 
 static void mga_free_page(drm_device_t *dev, unsigned long page)
 {
-	DRM_DEBUG("%s\n", __FUNCTION__);
-
-	if(page == 0UL) {
-		return;
-	}
+	if(!page) return;
 	atomic_dec(&virt_to_page(page)->count);
-	clear_bit(PG_locked, &virt_to_page(page)->flags);
-	wake_up(&virt_to_page(page)->wait);
+	clear_bit(PG_reserved, &virt_to_page(page)->flags);
 	free_page(page);
 	return;
 }
 
 static void mga_delay(void)
 {
-   	return;
-}
-
-#ifdef __i386__
-void mga_flush_write_combine(void)
-{
-   	int xchangeDummy;
-	DRM_DEBUG("%s\n", __FUNCTION__);
-
-   	__asm__ volatile(" push %%eax ; xchg %%eax, %0 ; pop %%eax" : : "m" (xchangeDummy));
-   	__asm__ volatile(" push %%eax ; push %%ebx ; push %%ecx ; push %%edx ;"
-			 " movl $0,%%eax ; cpuid ; pop %%edx ; pop %%ecx ; pop %%ebx ;"
-			 " pop %%eax" : /* no outputs */ :  /* no inputs */ );
-}
-#else
-void mga_flush_write_combine(void)
-{
+	return;
 }
-#endif
 
 /* These are two age tags that will never be sent to
  * the hardware */
@@ -113,13 +90,11 @@
    	drm_mga_freelist_t *item;
    	int i;
 
-	DRM_DEBUG("%s\n", __FUNCTION__);
-
    	dev_priv->head = drm_alloc(sizeof(drm_mga_freelist_t), DRM_MEM_DRIVER);
 	if(dev_priv->head == NULL) return -ENOMEM;
    	memset(dev_priv->head, 0, sizeof(drm_mga_freelist_t));
    	dev_priv->head->age = MGA_BUF_USED;
-   
+
    	for (i = 0; i < dma->buf_count; i++) {
 	   	buf = dma->buflist[ i ];
 	        buf_priv = buf->dev_private;
@@ -139,7 +114,7 @@
 		buf_priv->dispatched = 0;
 	   	dev_priv->head->next = item;
 	}
-   
+
    	return 0;
 }
 
@@ -149,15 +124,13 @@
    	drm_mga_freelist_t *item;
    	drm_mga_freelist_t *prev;
 
-	DRM_DEBUG("%s\n", __FUNCTION__);
-
    	item = dev_priv->head;
    	while(item) {
 	   	prev = item;
 	   	item = item->next;
 	   	drm_free(prev, sizeof(drm_mga_freelist_t), DRM_MEM_DRIVER);
 	}
-   
+
    	dev_priv->head = dev_priv->tail = NULL;
 }
 
@@ -170,19 +143,21 @@
    	unsigned long end;
 	int i;
 
-	DRM_DEBUG("%s\n", __FUNCTION__);
+	DRM_DEBUG("dispatch_status = 0x%02x\n", dev_priv->dispatch_status);
 	end = jiffies + (HZ*3);
     	while(1) {
-		if(!test_and_set_bit(MGA_IN_DISPATCH, 
+		if(!test_and_set_bit(MGA_IN_DISPATCH,
 				     &dev_priv->dispatch_status)) {
 			break;
 		}
 	   	if((signed)(end - jiffies) <= 0) {
-			DRM_ERROR("irqs: %d wanted %d\n", 
-				  atomic_read(&dev->total_irq), 
+			DRM_ERROR("irqs: %d wanted %d\n",
+				  atomic_read(&dev->total_irq),
 				  atomic_read(&dma->total_lost));
-			DRM_ERROR("lockup\n"); 
-			goto out_nolock;
+			DRM_ERROR("lockup: dispatch_status = 0x%02x,"
+				  " jiffies = %lu, end = %lu\n",
+				  dev_priv->dispatch_status, jiffies, end);
+			return;
 		}
 		for (i = 0 ; i < 2000 ; i++) mga_delay();
 	}
@@ -190,19 +165,20 @@
     	DRM_DEBUG("quiescent status : %x\n", MGA_READ(MGAREG_STATUS));
     	while((MGA_READ(MGAREG_STATUS) & 0x00030001) != 0x00020000) {
 		if((signed)(end - jiffies) <= 0) {
-			DRM_ERROR("irqs: %d wanted %d\n", 
-				  atomic_read(&dev->total_irq), 
+			DRM_ERROR("irqs: %d wanted %d\n",
+				  atomic_read(&dev->total_irq),
 				  atomic_read(&dma->total_lost));
-			DRM_ERROR("lockup\n"); 
-			goto out_status;
+			DRM_ERROR("lockup\n");
+			clear_bit(MGA_IN_DISPATCH, &dev_priv->dispatch_status);
+			return;
 		}
-		for (i = 0 ; i < 2000 ; i++) mga_delay();	  
+		for (i = 0 ; i < 2000 ; i++) mga_delay();
 	}
     	sarea_priv->dirty |= MGA_DMA_FLUSH;
 
-out_status:
     	clear_bit(MGA_IN_DISPATCH, &dev_priv->dispatch_status);
-out_nolock:
+	DRM_DEBUG("exit, dispatch_status = 0x%02x\n",
+		  dev_priv->dispatch_status);
 }
 
 static void mga_reset_freelist(drm_device_t *dev)
@@ -220,44 +196,44 @@
 }
 
 /* Least recently used :
- * These operations are not atomic b/c they are protected by the 
+ * These operations are not atomic b/c they are protected by the
  * hardware lock */
 
 drm_buf_t *mga_freelist_get(drm_device_t *dev)
 {
    	DECLARE_WAITQUEUE(entry, current);
-   	drm_mga_private_t *dev_priv = 
+   	drm_mga_private_t *dev_priv =
      		(drm_mga_private_t *) dev->dev_private;
 	drm_mga_freelist_t *prev;
    	drm_mga_freelist_t *next;
 	static int failed = 0;
+	int return_null = 0;
 
-	DRM_DEBUG("%s : tail->age : %d last_prim_age : %d\n", __FUNCTION__,
-	       dev_priv->tail->age, dev_priv->last_prim_age);
-   
 	if(failed >= 1000 && dev_priv->tail->age >= dev_priv->last_prim_age) {
-		DRM_DEBUG("I'm waiting on the freelist!!! %d\n", 
-		       dev_priv->last_prim_age);
-	   	set_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status);
-		current->state = TASK_INTERRUPTIBLE;
+		DRM_DEBUG("Waiting on freelist,"
+			  " tail->age = %d, last_prim_age= %d\n",
+			  dev_priv->tail->age,
+			  dev_priv->last_prim_age);
 	   	add_wait_queue(&dev_priv->buf_queue, &entry);
+		set_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status);
 	   	for (;;) {
+			current->state = TASK_INTERRUPTIBLE;
 		   	mga_dma_schedule(dev, 0);
-		   	if(!test_bit(MGA_IN_GETBUF, 
-				     &dev_priv->dispatch_status)) 
+			if(dev_priv->tail->age < dev_priv->last_prim_age)
 				break;
 		   	atomic_inc(&dev->total_sleeps);
 		   	schedule();
 		   	if (signal_pending(current)) {
-				clear_bit(MGA_IN_GETBUF,
-					  &dev_priv->dispatch_status);
-			   	goto failed_getbuf;
+				++return_null;
+				break;
 			}
 		}
-	   	current->state = TASK_RUNNING;
+		clear_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status);
+		current->state = TASK_RUNNING;
 	   	remove_wait_queue(&dev_priv->buf_queue, &entry);
+		if (return_null) return NULL;
 	}
-   
+
    	if(dev_priv->tail->age < dev_priv->last_prim_age) {
 		prev = dev_priv->tail->prev;
 	   	next = dev_priv->tail;
@@ -269,22 +245,19 @@
 	   	return next->buf;
 	}
 
-failed_getbuf:
 	failed++;
    	return NULL;
 }
 
 int mga_freelist_put(drm_device_t *dev, drm_buf_t *buf)
 {
-      	drm_mga_private_t *dev_priv = 
+      	drm_mga_private_t *dev_priv =
      		(drm_mga_private_t *) dev->dev_private;
    	drm_mga_buf_priv_t *buf_priv = buf->dev_private;
 	drm_mga_freelist_t *prev;
    	drm_mga_freelist_t *head;
    	drm_mga_freelist_t *next;
 
-	DRM_DEBUG("%s\n", __FUNCTION__);
-
    	if(buf_priv->my_freelist->age == MGA_BUF_USED) {
 		/* Discarded buffer, put it on the tail */
 		next = buf_priv->my_freelist;
@@ -294,7 +267,6 @@
 		next->prev = prev;
 		next->next = NULL;
 		dev_priv->tail = next;
-		DRM_DEBUG("Discarded\n");
 	} else {
 		/* Normally aged buffer, put it on the head + 1,
 		 * as the real head is a sentinal element
@@ -307,7 +279,7 @@
 		next->prev = head;
 		next->next = prev;
 	}
-   
+
    	return 0;
 }
 
@@ -318,42 +290,41 @@
    	int i, temp, size_of_buf;
    	int offset = init->reserved_map_agpstart;
 
-	DRM_DEBUG("%s\n", __FUNCTION__);
-   	dev_priv->primary_size = ((init->primary_size + PAGE_SIZE - 1) / 
+   	dev_priv->primary_size = ((init->primary_size + PAGE_SIZE - 1) /
 				  PAGE_SIZE) * PAGE_SIZE;
    	size_of_buf = dev_priv->primary_size / MGA_NUM_PRIM_BUFS;
 	dev_priv->warp_ucode_size = init->warp_ucode_size;
-   	dev_priv->prim_bufs = drm_alloc(sizeof(drm_mga_prim_buf_t *) * 
-					(MGA_NUM_PRIM_BUFS + 1), 
+   	dev_priv->prim_bufs = drm_alloc(sizeof(drm_mga_prim_buf_t *) *
+					(MGA_NUM_PRIM_BUFS + 1),
 					DRM_MEM_DRIVER);
    	if(dev_priv->prim_bufs == NULL) {
 		DRM_ERROR("Unable to allocate memory for prim_buf\n");
 		return -ENOMEM;
 	}
-   	memset(dev_priv->prim_bufs, 
+   	memset(dev_priv->prim_bufs,
 	       0, sizeof(drm_mga_prim_buf_t *) * (MGA_NUM_PRIM_BUFS + 1));
-   
+
    	temp = init->warp_ucode_size + dev_priv->primary_size;
 	temp = ((temp + PAGE_SIZE - 1) / PAGE_SIZE) * PAGE_SIZE;
-	   
-	dev_priv->ioremap = drm_ioremap(dev->agp->base + offset, 
+
+	dev_priv->ioremap = drm_ioremap(dev->agp->base + offset,
 					temp);
 	if(dev_priv->ioremap == NULL) {
-		DRM_DEBUG("Ioremap failed\n");
+		DRM_ERROR("Ioremap failed\n");
 		return -ENOMEM;
 	}
    	init_waitqueue_head(&dev_priv->wait_queue);
-   
+
    	for(i = 0; i < MGA_NUM_PRIM_BUFS; i++) {
-	   	prim_buffer = drm_alloc(sizeof(drm_mga_prim_buf_t), 
+	   	prim_buffer = drm_alloc(sizeof(drm_mga_prim_buf_t),
 					DRM_MEM_DRIVER);
 	   	if(prim_buffer == NULL) return -ENOMEM;
 	   	memset(prim_buffer, 0, sizeof(drm_mga_prim_buf_t));
 	   	prim_buffer->phys_head = offset + dev->agp->base;
-	   	prim_buffer->current_dma_ptr = 
-			prim_buffer->head = 
-			(u32 *) (dev_priv->ioremap + 
-				 offset - 
+	   	prim_buffer->current_dma_ptr =
+			prim_buffer->head =
+			(u32 *) (dev_priv->ioremap +
+				 offset -
 				 init->reserved_map_agpstart);
 	   	prim_buffer->num_dwords = 0;
 	   	prim_buffer->max_dwords = size_of_buf / sizeof(u32);
@@ -365,11 +336,11 @@
 	   	dev_priv->prim_bufs[i] = prim_buffer;
 	}
 	dev_priv->current_prim_idx = 0;
-        dev_priv->next_prim = 
-		dev_priv->last_prim = 
+        dev_priv->next_prim =
+		dev_priv->last_prim =
 		dev_priv->current_prim =
         	dev_priv->prim_bufs[0];
-	dev_priv->next_prim_age = 2;	
+	dev_priv->next_prim_age = 2;
 	dev_priv->last_prim_age = 1;
    	set_bit(MGA_BUF_IN_USE, &dev_priv->current_prim->buffer_status);
    	return 0;
@@ -386,13 +357,12 @@
    	int next_idx;
        	PRIMLOCALS;
 
-   	DRM_DEBUG("%s\n", __FUNCTION__);
    	dev_priv->last_prim = prim;
-   
+
  	/* We never check for overflow, b/c there is always room */
     	PRIMPTR(prim);
    	if(num_dwords <= 0) {
-		DRM_DEBUG("num_dwords == 0 when dispatched\n");
+		DRM_ERROR("num_dwords == 0 when dispatched\n");
 		goto out_prim_wait;
 	}
  	PRIMOUTREG( MGAREG_DMAPAD, 0);
@@ -403,32 +373,28 @@
 
 	end = jiffies + (HZ*3);
     	if(sarea_priv->dirty & MGA_DMA_FLUSH) {
-		DRM_DEBUG("Dma top flush\n");	   
 		while((MGA_READ(MGAREG_STATUS) & 0x00030001) != 0x00020000) {
 			if((signed)(end - jiffies) <= 0) {
-				DRM_ERROR("irqs: %d wanted %d\n", 
-					  atomic_read(&dev->total_irq), 
+				DRM_ERROR("irqs: %d wanted %d\n",
+					  atomic_read(&dev->total_irq),
 					  atomic_read(&dma->total_lost));
-				DRM_ERROR("lockup in fire primary "
-					  "(Dma Top Flush)\n");
+				DRM_ERROR("lockup (flush)\n");
 				goto out_prim_wait;
 			}
-	      
+
 			for (i = 0 ; i < 4096 ; i++) mga_delay();
 		}
 		sarea_priv->dirty &= ~(MGA_DMA_FLUSH);
 	} else {
-		DRM_DEBUG("Status wait\n");
 		while((MGA_READ(MGAREG_STATUS) & 0x00020001) != 0x00020000) {
 			if((signed)(end - jiffies) <= 0) {
-				DRM_ERROR("irqs: %d wanted %d\n", 
-					  atomic_read(&dev->total_irq), 
+				DRM_ERROR("irqs: %d wanted %d\n",
+					  atomic_read(&dev->total_irq),
 					  atomic_read(&dma->total_lost));
-				DRM_ERROR("lockup in fire primary "
-					  "(Status Wait)\n");
+				DRM_ERROR("lockup (wait)\n");
 				goto out_prim_wait;
 			}
-	   
+
 			for (i = 0 ; i < 4096 ; i++) mga_delay();
 		}
 	}
@@ -439,9 +405,9 @@
  	MGA_WRITE(MGAREG_PRIMEND, (phys_head + num_dwords * 4) | use_agp);
    	prim->num_dwords = 0;
 	sarea_priv->last_enqueue = prim->prim_age;
-    
+
    	next_idx = prim->idx + 1;
-    	if(next_idx >= MGA_NUM_PRIM_BUFS) 
+    	if(next_idx >= MGA_NUM_PRIM_BUFS)
 		next_idx = 0;
 
     	dev_priv->next_prim = dev_priv->prim_bufs[next_idx];
@@ -464,28 +430,26 @@
    	drm_device_dma_t  *dma      = dev->dma;
    	int next_prim_idx;
    	int ret = 0;
-   
+
    	/* This needs to reset the primary buffer if available,
 	 * we should collect stats on how many times it bites
 	 * it's tail */
-	DRM_DEBUG("%s\n", __FUNCTION__);
-   
+
    	next_prim_idx = dev_priv->current_prim_idx + 1;
    	if(next_prim_idx >= MGA_NUM_PRIM_BUFS)
      		next_prim_idx = 0;
    	prim_buffer = dev_priv->prim_bufs[next_prim_idx];
 	set_bit(MGA_IN_WAIT, &dev_priv->dispatch_status);
-   
+
       	/* In use is cleared in interrupt handler */
-   
+
    	if(test_and_set_bit(MGA_BUF_IN_USE, &prim_buffer->buffer_status)) {
 	   	add_wait_queue(&dev_priv->wait_queue, &entry);
-		current->state = TASK_INTERRUPTIBLE;
-
 	   	for (;;) {
+			current->state = TASK_INTERRUPTIBLE;
 		   	mga_dma_schedule(dev, 0);
-		   	if(!test_and_set_bit(MGA_BUF_IN_USE, 
-					     &prim_buffer->buffer_status)) 
+		   	if(!test_and_set_bit(MGA_BUF_IN_USE,
+					     &prim_buffer->buffer_status))
 				break;
 		   	atomic_inc(&dev->total_sleeps);
 		   	atomic_inc(&dma->total_missed_sched);
@@ -495,7 +459,7 @@
 			   	break;
 			}
 		}
-	   	current->state = TASK_RUNNING;
+		current->state = TASK_RUNNING;
 	   	remove_wait_queue(&dev_priv->wait_queue, &entry);
 	   	if(ret) return ret;
 	}
@@ -507,10 +471,10 @@
    	prim_buffer->sec_used = 0;
 	prim_buffer->prim_age = dev_priv->next_prim_age++;
 	if(prim_buffer->prim_age == 0 || prim_buffer->prim_age == 0xffffffff) {
-	   mga_flush_queue(dev);
-	   mga_dma_quiescent(dev);
-	   mga_reset_freelist(dev);
-	   prim_buffer->prim_age = (dev_priv->next_prim_age += 2);
+		mga_flush_queue(dev);
+		mga_dma_quiescent(dev);
+		mga_reset_freelist(dev);
+		prim_buffer->prim_age = (dev_priv->next_prim_age += 2);
 	}
 
 	/* Reset all buffer status stuff */
@@ -527,88 +491,72 @@
 static inline int mga_decide_to_fire(drm_device_t *dev)
 {
    	drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
-      	drm_device_dma_t  *dma	    = dev->dma;
-
-   	DRM_DEBUG("%s\n", __FUNCTION__);
 
    	if(test_bit(MGA_BUF_FORCE_FIRE, &dev_priv->next_prim->buffer_status)) {
-	   	atomic_inc(&dma->total_prio);
 	   	return 1;
 	}
 
 	if (test_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status) &&
 	    dev_priv->next_prim->num_dwords) {
-	   	atomic_inc(&dma->total_prio);
 	   	return 1;
 	}
 
 	if (test_bit(MGA_IN_FLUSH, &dev_priv->dispatch_status) &&
 	    dev_priv->next_prim->num_dwords) {
-	   	atomic_inc(&dma->total_prio);
 	   	return 1;
 	}
-   
+
    	if(atomic_read(&dev_priv->pending_bufs) <= MGA_NUM_PRIM_BUFS - 1) {
-		if(test_bit(MGA_BUF_SWAP_PENDING, 
+		if(test_bit(MGA_BUF_SWAP_PENDING,
 			    &dev_priv->next_prim->buffer_status)) {
-			atomic_inc(&dma->total_dmas);
 			return 1;
 		}
 	}
 
    	if(atomic_read(&dev_priv->pending_bufs) <= MGA_NUM_PRIM_BUFS / 2) {
 		if(dev_priv->next_prim->sec_used >= MGA_DMA_BUF_NR / 8) {
-			atomic_inc(&dma->total_hit);
 			return 1;
 		}
 	}
 
    	if(atomic_read(&dev_priv->pending_bufs) >= MGA_NUM_PRIM_BUFS / 2) {
 		if(dev_priv->next_prim->sec_used >= MGA_DMA_BUF_NR / 4) {
-			atomic_inc(&dma->total_missed_free);
 			return 1;
 		}
 	}
 
-   	atomic_inc(&dma->total_tried);
    	return 0;
 }
 
 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;
+	int               retval    = 0;
 
-   	if (test_and_set_bit(0, &dev->dma_flag)) {
-		atomic_inc(&dma->total_missed_dma);
+   	if (!dev_priv) return -EBUSY;
+	
+	if (test_and_set_bit(0, &dev->dma_flag)) {
 		retval = -EBUSY;
 		goto sch_out_wakeup;
 	}
-   
-	DRM_DEBUG("%s\n", __FUNCTION__);
 
-   	if(test_bit(MGA_IN_FLUSH, &dev_priv->dispatch_status) || 
+   	if(test_bit(MGA_IN_FLUSH, &dev_priv->dispatch_status) ||
 	   test_bit(MGA_IN_WAIT, &dev_priv->dispatch_status) ||
 	   test_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status)) {
 		locked = 1;
 	}
-   
-   	if (!locked && 
+
+   	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);
-		DRM_DEBUG("Not locked\n");
 		retval = -EBUSY;
 		goto sch_out_wakeup;
 	}
-   	DRM_DEBUG("I'm locked\n");
 
    	if(!test_and_set_bit(MGA_IN_DISPATCH, &dev_priv->dispatch_status)) {
 	   	/* Fire dma buffer */
 	   	if(mga_decide_to_fire(dev)) {
-		   	DRM_DEBUG("idx :%d\n", dev_priv->next_prim->idx);
-			clear_bit(MGA_BUF_FORCE_FIRE, 
+			clear_bit(MGA_BUF_FORCE_FIRE,
 				  &dev_priv->next_prim->buffer_status);
 		   	if(dev_priv->current_prim == dev_priv->next_prim) {
 				/* Schedule overflow for a later time */
@@ -619,10 +567,8 @@
 		} else {
 			clear_bit(MGA_IN_DISPATCH, &dev_priv->dispatch_status);
 		}
-	} else {
-		DRM_DEBUG("I can't get the dispatch lock\n");
 	}
-   	
+
 	if (!locked) {
 		if (drm_lock_free(dev, &dev->lock.hw_lock->lock,
 				  DRM_KERNEL_CONTEXT)) {
@@ -630,6 +576,8 @@
 		}
 	}
 
+	clear_bit(0, &dev->dma_flag);
+
 sch_out_wakeup:
       	if(test_bit(MGA_IN_FLUSH, &dev_priv->dispatch_status) &&
 	   atomic_read(&dev_priv->pending_bufs) == 0) {
@@ -638,18 +586,10 @@
 		wake_up_interruptible(&dev_priv->flush_queue);
 	}
 
-	if(test_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status) &&
-	   dev_priv->tail->age < dev_priv->last_prim_age) {
-		clear_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status);
-		DRM_DEBUG("Waking up buf queue\n");
+	if(test_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status)
+	   && dev_priv->tail->age < dev_priv->last_prim_age)
 		wake_up_interruptible(&dev_priv->buf_queue);
-	} else if (test_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status)) {
-	   	DRM_DEBUG("Not waking buf_queue on %d %d\n", 
-			  atomic_read(&dev->total_irq), 
-			  dev_priv->last_prim_age);
-	}
 
-   	clear_bit(0, &dev->dma_flag);
 	return retval;
 }
 
@@ -659,41 +599,40 @@
     	drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
     	drm_mga_prim_buf_t *last_prim_buffer;
 
-	DRM_DEBUG("%s\n", __FUNCTION__);
     	atomic_inc(&dev->total_irq);
 	if((MGA_READ(MGAREG_STATUS) & 0x00000001) != 0x00000001) return;
       	MGA_WRITE(MGAREG_ICLEAR, 0x00000001);
    	last_prim_buffer = dev_priv->last_prim;
     	last_prim_buffer->num_dwords = 0;
     	last_prim_buffer->sec_used = 0;
-	dev_priv->sarea_priv->last_dispatch = 
+	dev_priv->sarea_priv->last_dispatch =
 		dev_priv->last_prim_age = last_prim_buffer->prim_age;
       	clear_bit(MGA_BUF_IN_USE, &last_prim_buffer->buffer_status);
-   	wake_up_interruptible(&dev_priv->wait_queue);
       	clear_bit(MGA_BUF_SWAP_PENDING, &last_prim_buffer->buffer_status);
       	clear_bit(MGA_IN_DISPATCH, &dev_priv->dispatch_status);
       	atomic_dec(&dev_priv->pending_bufs);
    	queue_task(&dev->tq, &tq_immediate);
    	mark_bh(IMMEDIATE_BH);
+   	wake_up_interruptible(&dev_priv->wait_queue);
 }
 
 static void mga_dma_task_queue(void *device)
 {
-	DRM_DEBUG("%s\n", __FUNCTION__);
 	mga_dma_schedule((drm_device_t *)device, 0);
 }
 
 int mga_dma_cleanup(drm_device_t *dev)
 {
-	DRM_DEBUG("%s\n", __FUNCTION__);
-
 	if(dev->dev_private) {
-		drm_mga_private_t *dev_priv = 
+		drm_mga_private_t *dev_priv =
 			(drm_mga_private_t *) dev->dev_private;
-      
+
+		if (dev->irq) mga_flush_queue(dev);
+		mga_dma_quiescent(dev);
+
 		if(dev_priv->ioremap) {
-			int temp = (dev_priv->warp_ucode_size + 
-				    dev_priv->primary_size + 
+			int temp = (dev_priv->warp_ucode_size +
+				    dev_priv->primary_size +
 				    PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE;
 
 			drm_ioremapfree((void *) dev_priv->ioremap, temp);
@@ -714,7 +653,7 @@
 				}
 			}
 		   	drm_free(dev_priv->prim_bufs, sizeof(void *) *
-				 (MGA_NUM_PRIM_BUFS + 1), 
+				 (MGA_NUM_PRIM_BUFS + 1),
 				 DRM_MEM_DRIVER);
 		}
 		if(dev_priv->head != NULL) {
@@ -722,7 +661,7 @@
 		}
 
 
-		drm_free(dev->dev_private, sizeof(drm_mga_private_t), 
+		drm_free(dev->dev_private, sizeof(drm_mga_private_t),
 			 DRM_MEM_DRIVER);
 		dev->dev_private = NULL;
 	}
@@ -733,9 +672,6 @@
 static int mga_dma_initialize(drm_device_t *dev, drm_mga_init_t *init) {
 	drm_mga_private_t *dev_priv;
 	drm_map_t *sarea_map = NULL;
-	int i;
-
-	DRM_DEBUG("%s\n", __FUNCTION__);
 
 	dev_priv = drm_alloc(sizeof(drm_mga_private_t), DRM_MEM_DRIVER);
 	if(dev_priv == NULL) return -ENOMEM;
@@ -746,15 +682,14 @@
 	if((init->reserved_map_idx >= dev->map_count) ||
 	   (init->buffer_map_idx >= dev->map_count)) {
 		mga_dma_cleanup(dev);
-		DRM_DEBUG("reserved_map or buffer_map are invalid\n");
 		return -EINVAL;
 	}
-   
+
 	dev_priv->reserved_map_idx = init->reserved_map_idx;
 	dev_priv->buffer_map_idx = init->buffer_map_idx;
 	sarea_map = dev->maplist[0];
-	dev_priv->sarea_priv = (drm_mga_sarea_t *) 
-		((u8 *)sarea_map->handle + 
+	dev_priv->sarea_priv = (drm_mga_sarea_t *)
+		((u8 *)sarea_map->handle +
 		 init->sarea_priv_offset);
 
 	/* Scale primary size to the next page */
@@ -772,23 +707,17 @@
    	init_waitqueue_head(&dev_priv->flush_queue);
 	init_waitqueue_head(&dev_priv->buf_queue);
 	dev_priv->WarpPipe = 0xff000000;
+	dev_priv->vertexsize = 0;
 
-   	DRM_DEBUG("chipset: %d ucode_size: %d backOffset: %x depthOffset: %x\n",
-		  dev_priv->chipset, dev_priv->warp_ucode_size, 
+   	DRM_DEBUG("chipset=%d ucode_size=%d backOffset=%x depthOffset=%x\n",
+		  dev_priv->chipset, dev_priv->warp_ucode_size,
 		  dev_priv->backOffset, dev_priv->depthOffset);
    	DRM_DEBUG("cpp: %d sgram: %d stride: %d maccess: %x\n",
-		  dev_priv->cpp, dev_priv->sgram, dev_priv->stride, 
+		  dev_priv->cpp, dev_priv->sgram, dev_priv->stride,
 		  dev_priv->mAccess);
-   
-	memcpy(&dev_priv->WarpIndex, &init->WarpIndex, 
-	       sizeof(drm_mga_warp_index_t) * MGA_MAX_WARP_PIPES);
 
-   	for (i = 0 ; i < MGA_MAX_WARP_PIPES ; i++) 
-		DRM_DEBUG("warp pipe %d: installed: %d phys: %lx size: %x\n",
-			  i, 
-			  dev_priv->WarpIndex[i].installed,
-			  dev_priv->WarpIndex[i].phys_addr,
-			  dev_priv->WarpIndex[i].size);
+	memcpy(&dev_priv->WarpIndex, &init->WarpIndex,
+	       sizeof(drm_mga_warp_index_t) * MGA_MAX_WARP_PIPES);
 
    	if(mga_init_primary_bufs(dev, init) != 0) {
 		DRM_ERROR("Can not initialize primary buffers\n");
@@ -802,7 +731,7 @@
 		return -ENOMEM;
 	}
 
-   	dev_priv->status_page = 
+   	dev_priv->status_page =
 		ioremap_nocache(virt_to_bus((void *)dev_priv->real_status_page),
 				PAGE_SIZE);
 
@@ -813,15 +742,15 @@
 	}
 
    	/* Write status page when secend or softrap occurs */
-   	MGA_WRITE(MGAREG_PRIMPTR, 
+   	MGA_WRITE(MGAREG_PRIMPTR,
 		  virt_to_bus((void *)dev_priv->real_status_page) | 0x00000003);
-      
+
 
 	/* Private is now filled in, initialize the hardware */
 	{
 		PRIMLOCALS;
 		PRIMGETPTR( dev_priv );
-	   	   
+
 		PRIMOUTREG(MGAREG_DMAPAD, 0);
 		PRIMOUTREG(MGAREG_DMAPAD, 0);
 		PRIMOUTREG(MGAREG_DWGSYNC, 0x0100);
@@ -829,13 +758,13 @@
 		/* Poll for the first buffer to insure that
 		 * the status register will be correct
 		 */
-	   
+
 		mga_flush_write_combine();
 	   	MGA_WRITE(MGAREG_PRIMADDRESS, phys_head | TT_GENERAL);
 
-		MGA_WRITE(MGAREG_PRIMEND, ((phys_head + num_dwords * 4) | 
+		MGA_WRITE(MGAREG_PRIMEND, ((phys_head + num_dwords * 4) |
 					   PDEA_pagpxfer_enable));
-	   
+
 	   	while(MGA_READ(MGAREG_DWGSYNC) != 0x0100) ;
 	}
 
@@ -853,12 +782,10 @@
 	drm_file_t *priv = filp->private_data;
 	drm_device_t *dev = priv->dev;
 	drm_mga_init_t init;
-   
-   	DRM_DEBUG("%s\n", __FUNCTION__);
 
 	if (copy_from_user(&init, (drm_mga_init_t *)arg, sizeof(init)))
 		return -EFAULT;
-   
+
 	switch(init.func) {
 	case MGA_INIT_DMA:
 		return mga_dma_initialize(dev, &init);
@@ -874,7 +801,7 @@
 	int retcode;
 
 	if (!irq)     return -EINVAL;
-	
+
 	down(&dev->struct_sem);
 	if (dev->irq) {
 		up(&dev->struct_sem);
@@ -882,7 +809,7 @@
 	}
 	dev->irq = irq;
 	up(&dev->struct_sem);
-	
+
 	DRM_DEBUG("install irq handler %d\n", irq);
 
 	dev->context_flag     = 0;
@@ -923,7 +850,7 @@
 	irq	 = dev->irq;
 	dev->irq = 0;
 	up(&dev->struct_sem);
-	
+
 	if (!irq) return -EINVAL;
    	DRM_DEBUG("remove irq handler %d\n", irq);
       	MGA_WRITE(MGAREG_ICLEAR, 0x00000001);
@@ -938,12 +865,10 @@
 	drm_file_t	*priv	= filp->private_data;
 	drm_device_t	*dev	= priv->dev;
 	drm_control_t	ctl;
-   
+
 	if (copy_from_user(&ctl, (drm_control_t *)arg, sizeof(ctl)))
 		return -EFAULT;
 
-   	DRM_DEBUG("%s\n", __FUNCTION__);
-
 	switch (ctl.func) {
 	case DRM_INST_HANDLER:
 		return mga_irq_install(dev, ctl.irq);
@@ -960,31 +885,29 @@
   	drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
    	int ret = 0;
 
-   	DRM_DEBUG("%s\n", __FUNCTION__);
+   	if(!dev_priv) return 0;
 
-   	if(dev_priv == NULL) {
-	   	return 0;
-	}
-   
    	if(dev_priv->next_prim->num_dwords != 0) {
-   		current->state = TASK_INTERRUPTIBLE;
    		add_wait_queue(&dev_priv->flush_queue, &entry);
+		if (test_bit(MGA_IN_FLUSH, &dev_priv->dispatch_status)) 
+			DRM_ERROR("Incorrect mga_flush_queue logic\n");
 		set_bit(MGA_IN_FLUSH, &dev_priv->dispatch_status);
 		mga_dma_schedule(dev, 0);
    		for (;;) {
-	   		if (!test_bit(MGA_IN_FLUSH, 
-				      &dev_priv->dispatch_status)) 
+			current->state = TASK_INTERRUPTIBLE;
+	   		if (!test_bit(MGA_IN_FLUSH,
+				      &dev_priv->dispatch_status))
 				break;
 		   	atomic_inc(&dev->total_sleeps);
 	      		schedule();
 	      		if (signal_pending(current)) {
 		   		ret = -EINTR; /* Can't restart */
-				clear_bit(MGA_IN_FLUSH, 
+				clear_bit(MGA_IN_FLUSH,
 					  &dev_priv->dispatch_status);
 		   		break;
 			}
 		}
-   		current->state = TASK_RUNNING;
+		current->state = TASK_RUNNING;
    		remove_wait_queue(&dev_priv->flush_queue, &entry);
 	}
    	return ret;
@@ -1000,18 +923,19 @@
       	if(dev->dev_private == NULL) return;
 	if(dma->buflist == NULL) return;
 
-	DRM_DEBUG("%s\n", __FUNCTION__);
+	DRM_DEBUG("buf_count=%d\n", dma->buf_count);
+	
         mga_flush_queue(dev);
 
 	for (i = 0; i < dma->buf_count; i++) {
 	   	drm_buf_t *buf = dma->buflist[ i ];
 	   	drm_mga_buf_priv_t *buf_priv = buf->dev_private;
 
-		/* Only buffers that need to get reclaimed ever 
-		 * get set to free 
+		/* Only buffers that need to get reclaimed ever
+		 * get set to free
 		 */
 		if (buf->pid == pid  && buf_priv) {
-			if(buf_priv->my_freelist->age == MGA_BUF_USED) 
+			if(buf_priv->my_freelist->age == MGA_BUF_USED)
 		     		buf_priv->my_freelist->age = MGA_BUF_FREE;
 		}
 	}
@@ -1026,7 +950,6 @@
 	int		  ret	= 0;
 	drm_lock_t	  lock;
 
-	DRM_DEBUG("%s\n", __FUNCTION__);
 	if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock)))
 		return -EFAULT;
 
@@ -1035,21 +958,16 @@
 			  current->pid, lock.context);
 		return -EINVAL;
 	}
-   
-   	DRM_DEBUG("%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n",
-	       lock.context, current->pid, dev->lock.hw_lock->lock,
-	       lock.flags);
 
-	if (lock.context < 0) {
-		return -EINVAL;
-	}
-   
+	if (lock.context < 0) return -EINVAL;
+
 	/* Only one queue:
 	 */
 
 	if (!ret) {
 		add_wait_queue(&dev->lock.lock_queue, &entry);
 		for (;;) {
+			current->state = TASK_INTERRUPTIBLE;
 			if (!dev->lock.hw_lock) {
 				/* Device has been unregistered */
 				ret = -EINTR;
@@ -1062,10 +980,9 @@
 				atomic_inc(&dev->total_locks);
 				break;	/* Got lock */
 			}
-			
+
 				/* Contention */
 			atomic_inc(&dev->total_sleeps);
-			current->state = TASK_INTERRUPTIBLE;
 			schedule();
 			if (signal_pending(current)) {
 				ret = -ERESTARTSYS;
@@ -1075,7 +992,7 @@
 		current->state = TASK_RUNNING;
 		remove_wait_queue(&dev->lock.lock_queue, &entry);
 	}
-	
+
 	if (!ret) {
 		sigemptyset(&dev->sigmask);
 		sigaddset(&dev->sigmask, SIGSTOP);
@@ -1092,12 +1009,13 @@
 		   mga_dma_quiescent(dev);
 		}
 	}
-   
-	DRM_DEBUG("%d %s\n", lock.context, ret ? "interrupted" : "has lock");
+
+	if (ret) DRM_DEBUG("%d %s\n", lock.context,
+			   ret ? "interrupted" : "has lock");
 	return ret;
 }
-		
-int mga_flush_ioctl(struct inode *inode, struct file *filp, 
+
+int mga_flush_ioctl(struct inode *inode, struct file *filp,
 		    unsigned int cmd, unsigned long arg)
 {
        	drm_file_t	  *priv	  = filp->private_data;
@@ -1105,12 +1023,11 @@
 	drm_lock_t	  lock;
       	drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
 
-   	DRM_DEBUG("%s\n", __FUNCTION__);
 	if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock)))
 		return -EFAULT;
 
 	if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
-		DRM_ERROR("mga_flush_ioctl called without lock held\n");
+		DRM_ERROR("lock not held\n");
 		return -EINVAL;
 	}
 

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)