|
@@ -79,23 +79,22 @@ static int drm_setup(struct drm_device * dev)
|
|
|
*/
|
|
|
int drm_open(struct inode *inode, struct file *filp)
|
|
|
{
|
|
|
- struct drm_device *dev = NULL;
|
|
|
- int minor_id = iminor(inode);
|
|
|
+ struct drm_device *dev;
|
|
|
struct drm_minor *minor;
|
|
|
- int retcode = 0;
|
|
|
+ int retcode;
|
|
|
int need_setup = 0;
|
|
|
struct address_space *old_mapping;
|
|
|
struct address_space *old_imapping;
|
|
|
|
|
|
- minor = idr_find(&drm_minors_idr, minor_id);
|
|
|
- if (!minor)
|
|
|
- return -ENODEV;
|
|
|
-
|
|
|
- if (!(dev = minor->dev))
|
|
|
- return -ENODEV;
|
|
|
+ minor = drm_minor_acquire(iminor(inode));
|
|
|
+ if (IS_ERR(minor))
|
|
|
+ return PTR_ERR(minor);
|
|
|
|
|
|
- if (drm_device_is_unplugged(dev))
|
|
|
- return -ENODEV;
|
|
|
+ dev = minor->dev;
|
|
|
+ if (drm_device_is_unplugged(dev)) {
|
|
|
+ retcode = -ENODEV;
|
|
|
+ goto err_release;
|
|
|
+ }
|
|
|
|
|
|
if (!dev->open_count++)
|
|
|
need_setup = 1;
|
|
@@ -128,6 +127,8 @@ err_undo:
|
|
|
dev->dev_mapping = old_mapping;
|
|
|
mutex_unlock(&dev->struct_mutex);
|
|
|
dev->open_count--;
|
|
|
+err_release:
|
|
|
+ drm_minor_release(minor);
|
|
|
return retcode;
|
|
|
}
|
|
|
EXPORT_SYMBOL(drm_open);
|
|
@@ -143,33 +144,33 @@ EXPORT_SYMBOL(drm_open);
|
|
|
*/
|
|
|
int drm_stub_open(struct inode *inode, struct file *filp)
|
|
|
{
|
|
|
- struct drm_device *dev = NULL;
|
|
|
+ struct drm_device *dev;
|
|
|
struct drm_minor *minor;
|
|
|
- int minor_id = iminor(inode);
|
|
|
int err = -ENODEV;
|
|
|
const struct file_operations *new_fops;
|
|
|
|
|
|
DRM_DEBUG("\n");
|
|
|
|
|
|
mutex_lock(&drm_global_mutex);
|
|
|
- minor = idr_find(&drm_minors_idr, minor_id);
|
|
|
- if (!minor)
|
|
|
- goto out;
|
|
|
-
|
|
|
- if (!(dev = minor->dev))
|
|
|
- goto out;
|
|
|
+ minor = drm_minor_acquire(iminor(inode));
|
|
|
+ if (IS_ERR(minor))
|
|
|
+ goto out_unlock;
|
|
|
|
|
|
+ dev = minor->dev;
|
|
|
if (drm_device_is_unplugged(dev))
|
|
|
- goto out;
|
|
|
+ goto out_release;
|
|
|
|
|
|
new_fops = fops_get(dev->driver->fops);
|
|
|
if (!new_fops)
|
|
|
- goto out;
|
|
|
+ goto out_release;
|
|
|
|
|
|
replace_fops(filp, new_fops);
|
|
|
if (filp->f_op->open)
|
|
|
err = filp->f_op->open(inode, filp);
|
|
|
-out:
|
|
|
+
|
|
|
+out_release:
|
|
|
+ drm_minor_release(minor);
|
|
|
+out_unlock:
|
|
|
mutex_unlock(&drm_global_mutex);
|
|
|
return err;
|
|
|
}
|
|
@@ -453,7 +454,8 @@ int drm_lastclose(struct drm_device * dev)
|
|
|
int drm_release(struct inode *inode, struct file *filp)
|
|
|
{
|
|
|
struct drm_file *file_priv = filp->private_data;
|
|
|
- struct drm_device *dev = file_priv->minor->dev;
|
|
|
+ struct drm_minor *minor = file_priv->minor;
|
|
|
+ struct drm_device *dev = minor->dev;
|
|
|
int retcode = 0;
|
|
|
|
|
|
mutex_lock(&drm_global_mutex);
|
|
@@ -575,6 +577,8 @@ int drm_release(struct inode *inode, struct file *filp)
|
|
|
}
|
|
|
mutex_unlock(&drm_global_mutex);
|
|
|
|
|
|
+ drm_minor_release(minor);
|
|
|
+
|
|
|
return retcode;
|
|
|
}
|
|
|
EXPORT_SYMBOL(drm_release);
|