diff options
-rw-r--r-- | linux-core/drmP.h | 1 | ||||
-rw-r--r-- | linux-core/drm_agpsupport.c | 8 | ||||
-rw-r--r-- | linux-core/drm_drv.c | 6 | ||||
-rw-r--r-- | linux-core/drm_fops.c | 1 | ||||
-rw-r--r-- | linux/drmP.h | 1 | ||||
-rw-r--r-- | linux/drm_agpsupport.h | 8 | ||||
-rw-r--r-- | linux/drm_drv.h | 6 | ||||
-rw-r--r-- | linux/drm_fops.h | 1 |
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) { |