diff options
author | Dave Airlie <airlied@redhat.com> | 2008-08-14 09:36:34 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2008-08-14 09:36:34 +1000 |
commit | 2d4420c6669dbaead27346b8c7e1979edc94ae5a (patch) | |
tree | 134fcbc1e4b902f7e1918d32c991bf2923da2101 /linux-core/drm_fops.c | |
parent | 1c6abcefdc37f5cbb447e8fee1f3805fd7d19bea (diff) | |
parent | 2a65759d159478b126c660ef124777548dcc872c (diff) |
Merge branch 'radeon-gem-cs' into modesetting-gem
Conflicts:
libdrm/xf86drm.c
linux-core/Makefile.kernel
linux-core/drmP.h
linux-core/drm_compat.h
linux-core/drm_drv.c
linux-core/drm_stub.c
linux-core/drm_vm.c
shared-core/i915_dma.c
shared-core/r300_cmdbuf.c
shared-core/radeon_drv.h
Diffstat (limited to 'linux-core/drm_fops.c')
-rw-r--r-- | linux-core/drm_fops.c | 81 |
1 files changed, 23 insertions, 58 deletions
diff --git a/linux-core/drm_fops.c b/linux-core/drm_fops.c index 3b3a0a3c..7bc73d26 100644 --- a/linux-core/drm_fops.c +++ b/linux-core/drm_fops.c @@ -54,10 +54,11 @@ static int drm_setup(struct drm_device * dev) atomic_set(&dev->ioctl_count, 0); atomic_set(&dev->vma_count, 0); - dev->buf_use = 0; - atomic_set(&dev->buf_alloc, 0); - if (drm_core_check_feature(dev, DRIVER_HAVE_DMA)) { + if (drm_core_check_feature(dev, DRIVER_HAVE_DMA) && !drm_core_check_feature(dev, DRIVER_MODESET)) { + dev->buf_use = 0; + atomic_set(&dev->buf_alloc, 0); + i = drm_dma_setup(dev); if (i < 0) return i; @@ -221,7 +222,6 @@ static int drm_open_helper(struct inode *inode, struct file *filp, int minor_id = iminor(inode); struct drm_file *priv; int ret; - int i, j; if (filp->f_flags & O_EXCL) return -EBUSY; /* No exclusive opens */ @@ -246,22 +246,8 @@ static int drm_open_helper(struct inode *inode, struct file *filp, priv->lock_count = 0; INIT_LIST_HEAD(&priv->lhead); - INIT_LIST_HEAD(&priv->refd_objects); INIT_LIST_HEAD(&priv->fbs); - for (i = 0; i < _DRM_NO_REF_TYPES; ++i) { - ret = drm_ht_create(&priv->refd_object_hash[i], - DRM_FILE_HASH_ORDER); - if (ret) - break; - } - - if (ret) { - for (j = 0; j < i; ++j) - drm_ht_remove(&priv->refd_object_hash[j]); - goto out_free; - } - if (dev->driver->driver_features & DRIVER_GEM) drm_gem_open(dev, priv); @@ -275,28 +261,34 @@ static int drm_open_helper(struct inode *inode, struct file *filp, /* if there is no current master make this fd it */ mutex_lock(&dev->struct_mutex); if (!priv->minor->master) { - priv->minor->master = drm_get_master(priv->minor); + /* create a new master */ + priv->minor->master = drm_master_create(priv->minor); if (!priv->minor->master) { ret = -ENOMEM; goto out_free; } priv->is_master = 1; - priv->master = priv->minor->master; + /* take another reference for the copy in the local file priv */ + priv->master = drm_master_get(priv->minor->master); priv->authenticated = 1; + mutex_unlock(&dev->struct_mutex); if (dev->driver->master_create) { ret = dev->driver->master_create(dev, priv->master); if (ret) { - drm_put_master(priv->minor->master); - priv->minor->master = priv->master = NULL; + mutex_lock(&dev->struct_mutex); + /* drop both references if this fails */ + drm_master_put(&priv->minor->master); + drm_master_put(&priv->master); mutex_unlock(&dev->struct_mutex); goto out_free; } } } else { - priv->master = priv->minor->master; + /* get a reference to the master */ + priv->master = drm_master_get(priv->minor->master); mutex_unlock(&dev->struct_mutex); } @@ -346,33 +338,6 @@ int drm_fasync(int fd, struct file *filp, int on) } EXPORT_SYMBOL(drm_fasync); -static void drm_object_release(struct file *filp) -{ - struct drm_file *priv = filp->private_data; - struct list_head *head; - struct drm_ref_object *ref_object; - int i; - - /* - * Free leftover ref objects created by me. Note that we cannot use - * list_for_each() here, as the struct_mutex may be temporarily - * released by the remove_() functions, and thus the lists may be - * altered. - * Also, a drm_remove_ref_object() will not remove it - * from the list unless its refcount is 1. - */ - - head = &priv->refd_objects; - while (head->next != head) { - ref_object = list_entry(head->next, struct drm_ref_object, list); - drm_remove_ref_object(priv, ref_object); - head = &priv->refd_objects; - } - - for (i = 0; i < _DRM_NO_REF_TYPES; ++i) - drm_ht_remove(&priv->refd_object_hash[i]); -} - /** * Release file. * @@ -495,6 +460,8 @@ int drm_release(struct inode *inode, struct file *filp) if (drm_core_check_feature(dev, DRIVER_MODESET)) drm_fb_release(filp); + mutex_lock(&dev->struct_mutex); + if (file_priv->is_master) { struct drm_file *temp; list_for_each_entry(temp, &dev->filelist, lhead) { @@ -503,19 +470,17 @@ int drm_release(struct inode *inode, struct file *filp) temp->authenticated = 0; } - if (file_priv->minor->master == file_priv->master) - file_priv->minor->master = NULL; - drm_put_master(file_priv->master); + if (file_priv->minor->master == file_priv->master) { + /* drop the reference held my the minor */ + drm_master_put(&file_priv->minor->master); + } } - file_priv->master = NULL; + /* drop the reference held my the file priv */ + drm_master_put(&file_priv->master); file_priv->is_master = 0; - mutex_lock(&dev->struct_mutex); - drm_object_release(filp); - list_del(&file_priv->lhead); - mutex_unlock(&dev->struct_mutex); if (dev->driver->postclose) |