Rationalize fasync return values
[safe/jmp/linux-2.6] / drivers / gpu / drm / drm_fops.c
index f228523..e13cb62 100644 (file)
@@ -35,7 +35,6 @@
  */
 
 #include "drmP.h"
-#include "drm_sarea.h"
 #include <linux/poll.h>
 #include <linux/smp_lock.h>
 
@@ -55,10 +54,12 @@ 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;
@@ -133,10 +134,20 @@ int drm_open(struct inode *inode, struct file *filp)
                spin_lock(&dev->count_lock);
                if (!dev->open_count++) {
                        spin_unlock(&dev->count_lock);
-                       return drm_setup(dev);
+                       retcode = drm_setup(dev);
+                       goto out;
                }
                spin_unlock(&dev->count_lock);
        }
+out:
+       mutex_lock(&dev->struct_mutex);
+       if (minor->type == DRM_MINOR_LEGACY) {
+               BUG_ON((dev->dev_mapping != NULL) &&
+                       (dev->dev_mapping != inode->i_mapping));
+               if (dev->dev_mapping == NULL)
+                       dev->dev_mapping = inode->i_mapping;
+       }
+       mutex_unlock(&dev->struct_mutex);
 
        return retcode;
 }
@@ -172,6 +183,10 @@ int drm_stub_open(struct inode *inode, struct file *filp)
 
        old_fops = filp->f_op;
        filp->f_op = fops_get(&dev->driver->fops);
+       if (filp->f_op == NULL) {
+               filp->f_op = old_fops;
+               goto out;
+       }
        if (filp->f_op->open && (err = filp->f_op->open(inode, filp))) {
                fops_put(filp->f_op);
                filp->f_op = fops_get(old_fops);
@@ -241,6 +256,7 @@ static int drm_open_helper(struct inode *inode, struct file *filp,
        priv->lock_count = 0;
 
        INIT_LIST_HEAD(&priv->lhead);
+       INIT_LIST_HEAD(&priv->fbs);
 
        if (dev->driver->driver_features & DRIVER_GEM)
                drm_gem_open(dev, priv);
@@ -321,14 +337,10 @@ int drm_fasync(int fd, struct file *filp, int on)
 {
        struct drm_file *priv = filp->private_data;
        struct drm_device *dev = priv->minor->dev;
-       int retcode;
 
        DRM_DEBUG("fd = %d, device = 0x%lx\n", fd,
                  (long)old_encode_dev(priv->minor->device));
-       retcode = fasync_helper(fd, filp, on, &dev->buf_async);
-       if (retcode < 0)
-               return retcode;
-       return 0;
+       return fasync_helper(fd, filp, on, &dev->buf_async);
 }
 EXPORT_SYMBOL(drm_fasync);
 
@@ -441,6 +453,9 @@ int drm_release(struct inode *inode, struct file *filp)
        if (dev->driver->driver_features & DRIVER_GEM)
                drm_gem_release(dev, file_priv);
 
+       if (dev->driver->driver_features & DRIVER_MODESET)
+               drm_fb_release(file_priv);
+
        mutex_lock(&dev->ctxlist_mutex);
        if (!list_empty(&dev->ctxlist)) {
                struct drm_ctx_list *pos, *n;
@@ -465,6 +480,7 @@ int drm_release(struct inode *inode, struct file *filp)
        mutex_lock(&dev->struct_mutex);
 
        if (file_priv->is_master) {
+               struct drm_master *master = file_priv->master;
                struct drm_file *temp;
                list_for_each_entry(temp, &dev->filelist, lhead) {
                        if ((temp->master == file_priv->master) &&
@@ -472,6 +488,19 @@ int drm_release(struct inode *inode, struct file *filp)
                                temp->authenticated = 0;
                }
 
+               /**
+                * Since the master is disappearing, so is the
+                * possibility to lock.
+                */
+
+               if (master->lock.hw_lock) {
+                       if (dev->sigdata.lock == master->lock.hw_lock)
+                               dev->sigdata.lock = NULL;
+                       master->lock.hw_lock = NULL;
+                       master->lock.file_priv = NULL;
+                       wake_up_interruptible_all(&master->lock.lock_queue);
+               }
+
                if (file_priv->minor->master == file_priv->master) {
                        /* drop the reference held my the minor */
                        drm_master_put(&file_priv->minor->master);