From 7527d4ec81bdfb6554cbff8e9582f8ad8883ca26 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Wed, 2 Dec 2009 18:15:25 +0000 Subject: [PATCH] --- yaml --- r: 174499 b: refs/heads/master c: 862302ffe422378a5213f558fc5cdf62c37050a9 h: refs/heads/master i: 174497: c99bfe1cad175f393ba31526b485503ce1642099 174495: 2e504e32aed855d4710e03b469d0b8b48c2725eb v: v3 --- [refs] | 2 +- trunk/drivers/gpu/drm/drm_fops.c | 14 ++++++++++++++ trunk/drivers/gpu/drm/drm_stub.c | 11 +++++++++++ trunk/include/drm/drmP.h | 9 +++++++++ 4 files changed, 35 insertions(+), 1 deletion(-) diff --git a/[refs] b/[refs] index 0dcb6fc2befa..54522cc3f18a 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 9340d8cfeacd16cef1cbe94527f7baaed7640669 +refs/heads/master: 862302ffe422378a5213f558fc5cdf62c37050a9 diff --git a/trunk/drivers/gpu/drm/drm_fops.c b/trunk/drivers/gpu/drm/drm_fops.c index 8ac7fbf6b2b7..08d14df3bb42 100644 --- a/trunk/drivers/gpu/drm/drm_fops.c +++ b/trunk/drivers/gpu/drm/drm_fops.c @@ -300,6 +300,18 @@ static int drm_open_helper(struct inode *inode, struct file *filp, goto out_free; } } + mutex_lock(&dev->struct_mutex); + if (dev->driver->master_set) { + ret = dev->driver->master_set(dev, priv, true); + if (ret) { + /* 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; + } + } + mutex_unlock(&dev->struct_mutex); } else { /* get a reference to the master */ priv->master = drm_master_get(priv->minor->master); @@ -533,6 +545,8 @@ int drm_release(struct inode *inode, struct file *filp) if (file_priv->minor->master == file_priv->master) { /* drop the reference held my the minor */ + if (dev->driver->master_drop) + dev->driver->master_drop(dev, file_priv, true); drm_master_put(&file_priv->minor->master); } } diff --git a/trunk/drivers/gpu/drm/drm_stub.c b/trunk/drivers/gpu/drm/drm_stub.c index adb864dfef3e..2c1b52847e9e 100644 --- a/trunk/drivers/gpu/drm/drm_stub.c +++ b/trunk/drivers/gpu/drm/drm_stub.c @@ -174,6 +174,8 @@ void drm_master_put(struct drm_master **master) int drm_setmaster_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { + int ret = 0; + if (file_priv->is_master) return 0; @@ -188,6 +190,13 @@ int drm_setmaster_ioctl(struct drm_device *dev, void *data, mutex_lock(&dev->struct_mutex); file_priv->minor->master = drm_master_get(file_priv->master); file_priv->is_master = 1; + if (dev->driver->master_set) { + ret = dev->driver->master_set(dev, file_priv, false); + if (unlikely(ret != 0)) { + file_priv->is_master = 0; + drm_master_put(&file_priv->minor->master); + } + } mutex_unlock(&dev->struct_mutex); } @@ -204,6 +213,8 @@ int drm_dropmaster_ioctl(struct drm_device *dev, void *data, return -EINVAL; mutex_lock(&dev->struct_mutex); + if (dev->driver->master_drop) + dev->driver->master_drop(dev, file_priv, false); drm_master_put(&file_priv->minor->master); file_priv->is_master = 0; mutex_unlock(&dev->struct_mutex); diff --git a/trunk/include/drm/drmP.h b/trunk/include/drm/drmP.h index 1b72a526ba64..770772c014aa 100644 --- a/trunk/include/drm/drmP.h +++ b/trunk/include/drm/drmP.h @@ -774,6 +774,15 @@ struct drm_driver { /* Master routines */ int (*master_create)(struct drm_device *dev, struct drm_master *master); void (*master_destroy)(struct drm_device *dev, struct drm_master *master); + /** + * master_set is called whenever the minor master is set. + * master_drop is called whenever the minor master is dropped. + */ + + int (*master_set)(struct drm_device *dev, struct drm_file *file_priv, + bool from_open); + void (*master_drop)(struct drm_device *dev, struct drm_file *file_priv, + bool from_release); int (*proc_init)(struct drm_minor *minor); void (*proc_cleanup)(struct drm_minor *minor);