aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJung-uk Kim2007-10-17 14:50:29 -0500
committerEric Anholt2007-10-17 14:52:12 -0500
commit36120264ca8f43078f8748e022faeb9471edcb36 (patch)
tree6069352cee66872b65f2fdfeb27a09713c3dceee /bsd-core
parentec1162b212248042bf1317abcb3c47bb10db8aa3 (diff)
downloadexternal-libdrm-36120264ca8f43078f8748e022faeb9471edcb36.tar.gz
external-libdrm-36120264ca8f43078f8748e022faeb9471edcb36.tar.xz
external-libdrm-36120264ca8f43078f8748e022faeb9471edcb36.zip
Bug #11870: FreeBSD hardware lock cleanup fix with multiple opens by a process.
Previously, the lock would get released on the first close by the X Server (during AIGLX setup), and the Radeon driver would then hang in initialization due to unexpected failure in DRM calls that required the lock to be held. Based on a patch by Kostik Belousov.
Diffstat (limited to 'bsd-core')
-rw-r--r--bsd-core/drm_drv.c15
1 files changed, 9 insertions, 6 deletions
diff --git a/bsd-core/drm_drv.c b/bsd-core/drm_drv.c
index c36b78aa..d6868b9c 100644
--- a/bsd-core/drm_drv.c
+++ b/bsd-core/drm_drv.c
@@ -538,6 +538,7 @@ static int drm_load(drm_device_t *dev)
538 538
539 if (dev->driver.load != NULL) { 539 if (dev->driver.load != NULL) {
540 DRM_LOCK(); 540 DRM_LOCK();
541 /* Shared code returns -errno. */
541 retcode = -dev->driver.load(dev, 542 retcode = -dev->driver.load(dev,
542 dev->id_entry->driver_private); 543 dev->id_entry->driver_private);
543 DRM_UNLOCK(); 544 DRM_UNLOCK();
@@ -720,6 +721,9 @@ int drm_close(struct cdev *kdev, int flags, int fmt, DRM_STRUCTPROC *p)
720 return EINVAL; 721 return EINVAL;
721 } 722 }
722 723
724 if (--file_priv->refs != 0)
725 goto done;
726
723 if (dev->driver.preclose != NULL) 727 if (dev->driver.preclose != NULL)
724 dev->driver.preclose(dev, file_priv); 728 dev->driver.preclose(dev, file_priv);
725 729
@@ -795,17 +799,16 @@ int drm_close(struct cdev *kdev, int flags, int fmt, DRM_STRUCTPROC *p)
795 dev->buf_pgid = 0; 799 dev->buf_pgid = 0;
796#endif /* __NetBSD__ || __OpenBSD__ */ 800#endif /* __NetBSD__ || __OpenBSD__ */
797 801
798 if (--file_priv->refs == 0) { 802 if (dev->driver.postclose != NULL)
799 if (dev->driver.postclose != NULL) 803 dev->driver.postclose(dev, file_priv);
800 dev->driver.postclose(dev, file_priv); 804 TAILQ_REMOVE(&dev->files, file_priv, link);
801 TAILQ_REMOVE(&dev->files, file_priv, link); 805 free(file_priv, M_DRM);
802 free(file_priv, M_DRM);
803 }
804 806
805 /* ======================================================== 807 /* ========================================================
806 * End inline drm_release 808 * End inline drm_release
807 */ 809 */
808 810
811done:
809 atomic_inc( &dev->counts[_DRM_STAT_CLOSES] ); 812 atomic_inc( &dev->counts[_DRM_STAT_CLOSES] );
810#ifdef __FreeBSD__ 813#ifdef __FreeBSD__
811 device_unbusy(dev->device); 814 device_unbusy(dev->device);