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

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

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/char/drm/mga_drv.c linux/drivers/char/drm/mga_drv.c
@@ -1,6 +1,6 @@
 /* mga_drv.c -- Matrox g200/g400 driver -*- linux-c -*-
  * Created: Mon Dec 13 01:56:22 1999 by jhartmann@precisioninsight.com
- * 
+ *
  * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
  * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
  * All Rights Reserved.
@@ -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
@@ -35,11 +35,11 @@
 #include "mga_drv.h"
 
 #define MGA_NAME	 "mga"
-#define MGA_DESC	 "Matrox g200/g400"
-#define MGA_DATE	 "20000719"
-#define MGA_MAJOR	 1
+#define MGA_DESC	 "Matrox G200/G400"
+#define MGA_DATE	 "20000928"
+#define MGA_MAJOR	 2
 #define MGA_MINOR	 0
-#define MGA_PATCHLEVEL	 0
+#define MGA_PATCHLEVEL	 1
 
 static drm_device_t	      mga_device;
 drm_ctx_t		      mga_res_ctx;
@@ -123,7 +123,7 @@
 #endif
 
 MODULE_AUTHOR("VA Linux Systems, Inc.");
-MODULE_DESCRIPTION("Matrox g200/g400");
+MODULE_DESCRIPTION("Matrox G200/G400");
 MODULE_PARM(mga, "s");
 
 #ifndef MODULE
@@ -144,7 +144,7 @@
 static int mga_setup(drm_device_t *dev)
 {
 	int i;
-	
+
 	atomic_set(&dev->ioctl_count, 0);
 	atomic_set(&dev->vma_count, 0);
 	dev->buf_use	  = 0;
@@ -187,22 +187,22 @@
 
 	dev->ctx_start	    = 0;
 	dev->lck_start	    = 0;
-	
+
 	dev->buf_rp	  = dev->buf;
 	dev->buf_wp	  = dev->buf;
 	dev->buf_end	  = dev->buf + DRM_BSZ;
 	dev->buf_async	  = NULL;
 	init_waitqueue_head(&dev->buf_readers);
 	init_waitqueue_head(&dev->buf_writers);
-			
+
 	DRM_DEBUG("\n");
-			
+
 	/* The kernel's context could be created here, but is now created
 	   in drm_dma_enqueue.	This is more resource-efficient for
 	   hardware that does not do DMA, but may mean that
 	   drm_select_queue fails between the time the interrupt is
 	   initialized and the time the queues are initialized. */
-			
+
 	return 0;
 }
 
@@ -216,16 +216,17 @@
 
 	DRM_DEBUG("\n");
 
+	if (dev->dev_private) mga_dma_cleanup(dev);
 	if (dev->irq) mga_irq_uninstall(dev);
-	
+
 	down(&dev->struct_sem);
 	del_timer(&dev->timer);
-	
+
 	if (dev->devname) {
 		drm_free(dev->devname, strlen(dev->devname)+1, DRM_MEM_DRIVER);
 		dev->devname = NULL;
 	}
-	
+
 	if (dev->unique) {
 		drm_free(dev->unique, strlen(dev->unique)+1, DRM_MEM_DRIVER);
 		dev->unique = NULL;
@@ -243,7 +244,7 @@
 	if (dev->agp) {
 		drm_agp_mem_t *entry;
 		drm_agp_mem_t *nexte;
-		
+
 				/* Remove AGP resources, but leave dev->agp
                                    intact until cleanup is called. */
 		for (entry = dev->agp->memory; entry; entry = nexte) {
@@ -253,10 +254,10 @@
 			drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
 		}
 		dev->agp->memory = NULL;
-		
+
 		if (dev->agp->acquired && drm_agp.release)
 			(*drm_agp.release)();
-		
+
 		dev->agp->acquired = 0;
 		dev->agp->enabled  = 0;
 	}
@@ -268,7 +269,7 @@
 		}
 		dev->vmalist = NULL;
 	}
-	
+
 				/* Clear map area and mtrr information */
 	if (dev->maplist) {
 		for (i = 0; i < dev->map_count; i++) {
@@ -304,7 +305,7 @@
 		dev->maplist   = NULL;
 		dev->map_count = 0;
 	}
-	
+
 	if (dev->queuelist) {
 		for (i = 0; i < dev->queue_count; i++) {
 			drm_waitlist_destroy(&dev->queuelist[i]->waitlist);
@@ -330,7 +331,7 @@
 		wake_up_interruptible(&dev->lock.lock_queue);
 	}
 	up(&dev->struct_sem);
-	
+
 	return 0;
 }
 
@@ -347,11 +348,10 @@
 	memset((void *)dev, 0, sizeof(*dev));
 	dev->count_lock	  = SPIN_LOCK_UNLOCKED;
 	sema_init(&dev->struct_sem, 1);
-	
+
 #ifdef MODULE
 	drm_parse_options(mga);
 #endif
-	DRM_DEBUG("doing misc_register\n");
 	if ((retcode = misc_register(&mga_misc))) {
 		DRM_ERROR("Cannot register \"%s\"\n", MGA_NAME);
 		return retcode;
@@ -359,11 +359,8 @@
 	dev->device = MKDEV(MISC_MAJOR, mga_misc.minor);
 	dev->name   = MGA_NAME;
 
-   	DRM_DEBUG("doing mem init\n");
 	drm_mem_init();
-	DRM_DEBUG("doing proc init\n");
 	drm_proc_init(dev);
-	DRM_DEBUG("doing agp init\n");
 	dev->agp    = drm_agp_init();
       	if(dev->agp == NULL) {
 	   	DRM_INFO("The mga drm module requires the agpgart module"
@@ -380,7 +377,6 @@
 				      MTRR_TYPE_WRCOMB,
 				      1);
 #endif
-	DRM_DEBUG("doing ctxbitmap init\n");
 	if((retcode = drm_ctxbitmap_init(dev))) {
 		DRM_ERROR("Cannot allocate memory for context bitmap.\n");
 		drm_proc_cleanup();
@@ -407,7 +403,7 @@
 	drm_device_t	      *dev = &mga_device;
 
 	DRM_DEBUG("\n");
-	
+
 	drm_proc_cleanup();
 	if (misc_deregister(&mga_misc)) {
 		DRM_ERROR("Cannot unload module\n");
@@ -415,11 +411,10 @@
 		DRM_INFO("Module unloaded\n");
 	}
 	drm_ctxbitmap_cleanup(dev);
-	mga_dma_cleanup(dev);
 #ifdef CONFIG_MTRR
    	if(dev->agp && dev->agp->agp_mtrr) {
 	   	int retval;
-	   	retval = mtrr_del(dev->agp->agp_mtrr, 
+	   	retval = mtrr_del(dev->agp->agp_mtrr,
 				  dev->agp->agp_info.aper_base,
 				  dev->agp->agp_info.aper_size * 1024*1024);
 	   	DRM_DEBUG("mtrr_del = %d\n", retval);
@@ -477,7 +472,7 @@
 {
 	drm_device_t  *dev    = &mga_device;
 	int	      retcode = 0;
-	
+
 	DRM_DEBUG("open_count = %d\n", dev->open_count);
 	if (!(retcode = drm_open_helper(inode, filp, dev))) {
 #if LINUX_VERSION_CODE < 0x020333
@@ -508,22 +503,27 @@
 	if (dev->lock.hw_lock && _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)
 	    && dev->lock.pid == current->pid) {
 	      	mga_reclaim_buffers(dev, priv->pid);
-		DRM_ERROR("Process %d dead, freeing lock for context %d\n",
-			  current->pid,
-			  _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
+		DRM_INFO("Process %d dead (ctx %d, d_s = 0x%02x)\n",
+			 current->pid,
+			 _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock),
+			 dev->dev_private ?
+			 ((drm_mga_private_t *)dev->dev_private)
+			 ->dispatch_status
+			 : 0);
+
+		if (dev->dev_private)
+			((drm_mga_private_t *)dev->dev_private)
+				->dispatch_status &= MGA_IN_DISPATCH;
+		
 		drm_lock_free(dev,
 			      &dev->lock.hw_lock->lock,
 			      _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
-		
-				/* FIXME: may require heavy-handed reset of
-                                   hardware at this point, possibly
-                                   processed via a callback to the X
-                                   server. */
 	} else if (dev->lock.hw_lock) {
 	   	/* The lock is required to reclaim buffers */
 	   	DECLARE_WAITQUEUE(entry, current);
 	   	add_wait_queue(&dev->lock.lock_queue, &entry);
 		for (;;) {
+			current->state = TASK_INTERRUPTIBLE;
 			if (!dev->lock.hw_lock) {
 				/* Device has been unregistered */
 				retcode = -EINTR;
@@ -535,10 +535,9 @@
 				dev->lock.lock_time = jiffies;
 				atomic_inc(&dev->total_locks);
 				break;	/* Got lock */
-			}			
+			}
 				/* Contention */
 			atomic_inc(&dev->total_sleeps);
-			current->state = TASK_INTERRUPTIBLE;
 			schedule();
 			if (signal_pending(current)) {
 				retcode = -ERESTARTSYS;
@@ -549,6 +548,9 @@
 		remove_wait_queue(&dev->lock.lock_queue, &entry);
 	   	if(!retcode) {
 		   	mga_reclaim_buffers(dev, priv->pid);
+			if (dev->dev_private)
+				((drm_mga_private_t *)dev->dev_private)
+					->dispatch_status &= MGA_IN_DISPATCH;
 		   	drm_lock_free(dev, &dev->lock.hw_lock->lock,
 				      DRM_KERNEL_CONTEXT);
 		}
@@ -556,12 +558,19 @@
 	drm_fasync(-1, filp, 0);
 
 	down(&dev->struct_sem);
+	if (priv->remove_auth_on_close == 1) {
+		drm_file_t *temp = dev->file_first;
+		while(temp) {
+			temp->authenticated = 0;
+			temp = temp->next;
+		}
+	}
 	if (priv->prev) priv->prev->next = priv->next;
 	else		dev->file_first	 = priv->next;
 	if (priv->next) priv->next->prev = priv->prev;
 	else		dev->file_last	 = priv->prev;
 	up(&dev->struct_sem);
-	
+
 	drm_free(priv, sizeof(*priv), DRM_MEM_FILES);
 #if LINUX_VERSION_CODE < 0x020333
 	MOD_DEC_USE_COUNT; /* Needed before Linux 2.3.51 */
@@ -602,9 +611,6 @@
 	atomic_inc(&dev->ioctl_count);
 	atomic_inc(&dev->total_ioctl);
 	++priv->ioctl_count;
-	
-	DRM_DEBUG("pid = %d, cmd = 0x%02x, nr = 0x%02x, dev 0x%x, auth = %d\n",
-		  current->pid, cmd, nr, dev->device, priv->authenticated);
 
 	if (nr >= MGA_IOCTL_COUNT) {
 		retcode = -EINVAL;
@@ -613,7 +619,10 @@
 		func	  = ioctl->func;
 
 		if (!func) {
-			DRM_DEBUG("no function\n");
+			DRM_DEBUG("no function: pid = %d, cmd = 0x%02x,"
+				  " nr = 0x%02x, dev 0x%x, auth = %d\n",
+				  current->pid, cmd, nr, dev->device,
+				  priv->authenticated);
 			retcode = -EINVAL;
 		} else if ((ioctl->root_only && !capable(CAP_SYS_ADMIN))
 			    || (ioctl->auth_needed && !priv->authenticated)) {
@@ -622,7 +631,7 @@
 			retcode = (func)(inode, filp, cmd, arg);
 		}
 	}
-	
+
 	atomic_dec(&dev->ioctl_count);
 	return retcode;
 }
@@ -636,16 +645,13 @@
 
 	if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock)))
 		return -EFAULT;
-	
+
 	if (lock.context == DRM_KERNEL_CONTEXT) {
 		DRM_ERROR("Process %d using kernel context %d\n",
 			  current->pid, lock.context);
 		return -EINVAL;
 	}
 
-	DRM_DEBUG("%d frees lock (%d holds)\n",
-		  lock.context,
-		  _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
 	atomic_inc(&dev->total_unlocks);
 	if (_DRM_LOCK_IS_CONT(dev->lock.hw_lock->lock))
 		atomic_inc(&dev->total_contends);
@@ -653,9 +659,7 @@
 	mga_dma_schedule(dev, 1);
 
 	if (drm_lock_free(dev, &dev->lock.hw_lock->lock,
-			  DRM_KERNEL_CONTEXT)) {
-	   DRM_ERROR("\n");
-	}
+			  DRM_KERNEL_CONTEXT)) DRM_ERROR("\n");
 
 	unblock_all_signals();
 	return 0;

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