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
- Lines: 356
- Date:
Sun Oct 1 20:00:00 2000
- Orig file:
v2.4.0-test8/linux/drivers/char/drm/mga_drv.c
- Orig date:
Tue Aug 29 21:09:10 2000
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)