summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--linux-core/drmP.h1
-rw-r--r--linux-core/drm_agpsupport.c8
-rw-r--r--linux-core/drm_drv.c6
-rw-r--r--linux-core/drm_fops.c1
-rw-r--r--linux/drmP.h1
-rw-r--r--linux/drm_agpsupport.h8
-rw-r--r--linux/drm_drv.h6
-rw-r--r--linux/drm_fops.h1
8 files changed, 24 insertions, 8 deletions
diff --git a/linux-core/drmP.h b/linux-core/drmP.h
index efbc30c0..7c7428ba 100644
--- a/linux-core/drmP.h
+++ b/linux-core/drmP.h
@@ -448,6 +448,7 @@ typedef struct drm_file {
struct drm_file *prev;
struct drm_device *dev;
int remove_auth_on_close;
+ unsigned long lock_count;
} drm_file_t;
diff --git a/linux-core/drm_agpsupport.c b/linux-core/drm_agpsupport.c
index 35dd866f..22790900 100644
--- a/linux-core/drm_agpsupport.c
+++ b/linux-core/drm_agpsupport.c
@@ -147,7 +147,7 @@ int DRM(agp_alloc)(struct inode *inode, struct file *filp,
return -ENOMEM;
}
- entry->handle = (unsigned long)memory->memory;
+ entry->handle = (unsigned long)memory->key;
entry->memory = memory;
entry->bound = 0;
entry->pages = pages;
@@ -187,6 +187,7 @@ int DRM(agp_unbind)(struct inode *inode, struct file *filp,
drm_device_t *dev = priv->dev;
drm_agp_binding_t request;
drm_agp_mem_t *entry;
+ int ret;
if (!dev->agp || !dev->agp->acquired) return -EINVAL;
if (copy_from_user(&request, (drm_agp_binding_t *)arg, sizeof(request)))
@@ -194,7 +195,10 @@ int DRM(agp_unbind)(struct inode *inode, struct file *filp,
if (!(entry = DRM(agp_lookup_entry)(dev, request.handle)))
return -EINVAL;
if (!entry->bound) return -EINVAL;
- return DRM(unbind_agp)(entry->memory);
+ ret = DRM(unbind_agp)(entry->memory);
+ if (ret == 0)
+ entry->bound = 0;
+ return ret;
}
int DRM(agp_bind)(struct inode *inode, struct file *filp,
diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c
index 0a4f3aeb..b2070d32 100644
--- a/linux-core/drm_drv.c
+++ b/linux-core/drm_drv.c
@@ -766,7 +766,7 @@ int DRM(release)( struct inode *inode, struct file *filp )
DRM_DEBUG( "pid = %d, device = 0x%lx, open_count = %d\n",
current->pid, (long)dev->device, dev->open_count );
- if ( dev->lock.hw_lock &&
+ if ( priv->lock_count && dev->lock.hw_lock &&
_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) &&
dev->lock.filp == filp ) {
DRM_DEBUG( "File %p released, freeing lock for context %d\n",
@@ -784,7 +784,7 @@ int DRM(release)( struct inode *inode, struct file *filp )
server. */
}
#if __HAVE_RELEASE
- else if ( dev->lock.hw_lock ) {
+ else if ( priv->lock_count && dev->lock.hw_lock ) {
/* The lock is required to reclaim buffers */
DECLARE_WAITQUEUE( entry, current );
@@ -933,6 +933,8 @@ int DRM(lock)( struct inode *inode, struct file *filp,
dev->lck_start = start = get_cycles();
#endif
+ ++priv->lock_count;
+
if ( copy_from_user( &lock, (drm_lock_t *)arg, sizeof(lock) ) )
return -EFAULT;
diff --git a/linux-core/drm_fops.c b/linux-core/drm_fops.c
index 10d1aed1..833409f0 100644
--- a/linux-core/drm_fops.c
+++ b/linux-core/drm_fops.c
@@ -57,6 +57,7 @@ int DRM(open_helper)(struct inode *inode, struct file *filp, drm_device_t *dev)
priv->dev = dev;
priv->ioctl_count = 0;
priv->authenticated = capable(CAP_SYS_ADMIN);
+ priv->lock_count = 0;
down(&dev->struct_sem);
if (!dev->file_last) {
diff --git a/linux/drmP.h b/linux/drmP.h
index efbc30c0..7c7428ba 100644
--- a/linux/drmP.h
+++ b/linux/drmP.h
@@ -448,6 +448,7 @@ typedef struct drm_file {
struct drm_file *prev;
struct drm_device *dev;
int remove_auth_on_close;
+ unsigned long lock_count;
} drm_file_t;
diff --git a/linux/drm_agpsupport.h b/linux/drm_agpsupport.h
index 35dd866f..22790900 100644
--- a/linux/drm_agpsupport.h
+++ b/linux/drm_agpsupport.h
@@ -147,7 +147,7 @@ int DRM(agp_alloc)(struct inode *inode, struct file *filp,
return -ENOMEM;
}
- entry->handle = (unsigned long)memory->memory;
+ entry->handle = (unsigned long)memory->key;
entry->memory = memory;
entry->bound = 0;
entry->pages = pages;
@@ -187,6 +187,7 @@ int DRM(agp_unbind)(struct inode *inode, struct file *filp,
drm_device_t *dev = priv->dev;
drm_agp_binding_t request;
drm_agp_mem_t *entry;
+ int ret;
if (!dev->agp || !dev->agp->acquired) return -EINVAL;
if (copy_from_user(&request, (drm_agp_binding_t *)arg, sizeof(request)))
@@ -194,7 +195,10 @@ int DRM(agp_unbind)(struct inode *inode, struct file *filp,
if (!(entry = DRM(agp_lookup_entry)(dev, request.handle)))
return -EINVAL;
if (!entry->bound) return -EINVAL;
- return DRM(unbind_agp)(entry->memory);
+ ret = DRM(unbind_agp)(entry->memory);
+ if (ret == 0)
+ entry->bound = 0;
+ return ret;
}
int DRM(agp_bind)(struct inode *inode, struct file *filp,
diff --git a/linux/drm_drv.h b/linux/drm_drv.h
index 0a4f3aeb..b2070d32 100644
--- a/linux/drm_drv.h
+++ b/linux/drm_drv.h
@@ -766,7 +766,7 @@ int DRM(release)( struct inode *inode, struct file *filp )
DRM_DEBUG( "pid = %d, device = 0x%lx, open_count = %d\n",
current->pid, (long)dev->device, dev->open_count );
- if ( dev->lock.hw_lock &&
+ if ( priv->lock_count && dev->lock.hw_lock &&
_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) &&
dev->lock.filp == filp ) {
DRM_DEBUG( "File %p released, freeing lock for context %d\n",
@@ -784,7 +784,7 @@ int DRM(release)( struct inode *inode, struct file *filp )
server. */
}
#if __HAVE_RELEASE
- else if ( dev->lock.hw_lock ) {
+ else if ( priv->lock_count && dev->lock.hw_lock ) {
/* The lock is required to reclaim buffers */
DECLARE_WAITQUEUE( entry, current );
@@ -933,6 +933,8 @@ int DRM(lock)( struct inode *inode, struct file *filp,
dev->lck_start = start = get_cycles();
#endif
+ ++priv->lock_count;
+
if ( copy_from_user( &lock, (drm_lock_t *)arg, sizeof(lock) ) )
return -EFAULT;
diff --git a/linux/drm_fops.h b/linux/drm_fops.h
index 10d1aed1..833409f0 100644
--- a/linux/drm_fops.h
+++ b/linux/drm_fops.h
@@ -57,6 +57,7 @@ int DRM(open_helper)(struct inode *inode, struct file *filp, drm_device_t *dev)
priv->dev = dev;
priv->ioctl_count = 0;
priv->authenticated = capable(CAP_SYS_ADMIN);
+ priv->lock_count = 0;
down(&dev->struct_sem);
if (!dev->file_last) {