Bring some drm module changes over from the XFree86 trunk:
authorDavid Dawes <dawes@xfree86.org>
Thu, 17 Apr 2003 18:41:28 +0000 (18:41 +0000)
committerDavid Dawes <dawes@xfree86.org>
Thu, 17 Apr 2003 18:41:28 +0000 (18:41 +0000)
- Reset 'bound' flag for an agp entry after undbind succeeded in
    drm_agpsupport.h (Egbert Eich).
- Ignore hw_lock for drm device if lock was set by a different instance (ie
    Xserver) to prevent second server from spinning in driver release
    function (currently only relevant for i8xx drm drivers) (David Dawes).
- Use the agpgart "key" for the unique handle for bindings rather than the
    memory address (the key is guaranteed to be unique) (David Dawes).

linux-core/drmP.h
linux-core/drm_agpsupport.c
linux-core/drm_drv.c
linux-core/drm_fops.c
linux/drmP.h
linux/drm_agpsupport.h
linux/drm_drv.h
linux/drm_fops.h

index efbc30c..7c7428b 100644 (file)
@@ -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;
 
 
index 35dd866..2279090 100644 (file)
@@ -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,
index 0a4f3ae..b2070d3 100644 (file)
@@ -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;
 
index 10d1aed..833409f 100644 (file)
@@ -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) {
index efbc30c..7c7428b 100644 (file)
@@ -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;
 
 
index 35dd866..2279090 100644 (file)
@@ -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,
index 0a4f3ae..b2070d3 100644 (file)
@@ -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;
 
index 10d1aed..833409f 100644 (file)
@@ -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) {