patch-2.4.20 linux-2.4.20/drivers/char/drm/drm_fops.h

Next file: linux-2.4.20/drivers/char/drm/drm_init.h
Previous file: linux-2.4.20/drivers/char/drm/drm_drv.h
Back to the patch index
Back to the overall index

diff -urN linux-2.4.19/drivers/char/drm/drm_fops.h linux-2.4.20/drivers/char/drm/drm_fops.h
@@ -30,7 +30,6 @@
  *    Gareth Hughes <gareth@valinux.com>
  */
 
-#define __NO_VERSION__
 #include "drmP.h"
 #include <linux/poll.h>
 
@@ -97,6 +96,23 @@
 
 	DRM_DEBUG("pid = %d, device = 0x%x, open_count = %d\n",
 		  current->pid, dev->device, dev->open_count);
+	if ( dev->lock.hw_lock &&
+	     _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) &&
+	     dev->lock.pid == current->pid ) {
+		DRM_DEBUG( "Process %d closed fd, freeing lock for context %d\n",
+			   current->pid,
+			   _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock) );
+#if __HAVE_RELEASE
+		DRIVER_RELEASE();
+#endif
+		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. */
+	}
 	return 0;
 }
 
@@ -125,21 +141,31 @@
 	int	      avail;
 	int	      send;
 	int	      cur;
+	DECLARE_WAITQUEUE(wait, current);
 
 	DRM_DEBUG("%p, %p\n", dev->buf_rp, dev->buf_wp);
 
+	add_wait_queue(&dev->buf_readers, &wait);
+	set_current_state(TASK_INTERRUPTIBLE);
 	while (dev->buf_rp == dev->buf_wp) {
 		DRM_DEBUG("  sleeping\n");
 		if (filp->f_flags & O_NONBLOCK) {
+			remove_wait_queue(&dev->buf_readers, &wait);
+			set_current_state(TASK_RUNNING);
 			return -EAGAIN;
 		}
-		interruptible_sleep_on(&dev->buf_readers);
+		schedule(); /* wait for dev->buf_readers */
 		if (signal_pending(current)) {
 			DRM_DEBUG("  interrupted\n");
+			remove_wait_queue(&dev->buf_readers, &wait);
+			set_current_state(TASK_RUNNING);
 			return -ERESTARTSYS;
 		}
 		DRM_DEBUG("  awake\n");
+		set_current_state(TASK_INTERRUPTIBLE);
 	}
+	remove_wait_queue(&dev->buf_readers, &wait);
+	set_current_state(TASK_RUNNING);
 
 	left  = (dev->buf_rp + DRM_BSZ - dev->buf_wp) % DRM_BSZ;
 	avail = DRM_BSZ - left;
@@ -191,24 +217,8 @@
 		send -= count;
 	}
 
-#if LINUX_VERSION_CODE < 0x020315 && !defined(KILLFASYNCHASTHREEPARAMETERS)
-	/* The extra parameter to kill_fasync was added in 2.3.21, and is
-           _not_ present in _stock_ 2.2.14 and 2.2.15.  However, some
-           distributions patch 2.2.x kernels to add this parameter.  The
-           Makefile.linux attempts to detect this addition and defines
-           KILLFASYNCHASTHREEPARAMETERS if three parameters are found. */
-	if (dev->buf_async) kill_fasync(dev->buf_async, SIGIO);
-#else
-
-				/* Parameter added in 2.3.21. */
-#if LINUX_VERSION_CODE < 0x020400
-	if (dev->buf_async) kill_fasync(dev->buf_async, SIGIO, POLL_IN);
-#else
-				/* Type of first parameter changed in
-                                   Linux 2.4.0-test2... */
 	if (dev->buf_async) kill_fasync(&dev->buf_async, SIGIO, POLL_IN);
-#endif
-#endif
+
 	DRM_DEBUG("waking\n");
 	wake_up_interruptible(&dev->buf_readers);
 	return 0;

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