Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 293798
b: refs/heads/master
c: 2c07a21
h: refs/heads/master
v: v3
  • Loading branch information
Dave Airlie committed Mar 15, 2012
1 parent 34540fb commit 6fee277
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: cbc7e22151d99ed1dd7649d268ad3d81b9e6255a
refs/heads/master: 2c07a21d6fb0be47fda696a618b726ea258ed1dd
4 changes: 4 additions & 0 deletions trunk/drivers/gpu/drm/drm_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,10 @@ long drm_ioctl(struct file *filp,
unsigned int usize, asize;

dev = file_priv->minor->dev;

if (drm_device_is_unplugged(dev))
return -ENODEV;

atomic_inc(&dev->ioctl_count);
atomic_inc(&dev->counts[_DRM_STAT_IOCTLS]);
++file_priv->ioctl_count;
Expand Down
8 changes: 8 additions & 0 deletions trunk/drivers/gpu/drm/drm_fops.c
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,9 @@ int drm_open(struct inode *inode, struct file *filp)
if (!(dev = minor->dev))
return -ENODEV;

if (drm_device_is_unplugged(dev))
return -ENODEV;

retcode = drm_open_helper(inode, filp, dev);
if (!retcode) {
atomic_inc(&dev->counts[_DRM_STAT_OPENS]);
Expand Down Expand Up @@ -181,6 +184,9 @@ int drm_stub_open(struct inode *inode, struct file *filp)
if (!(dev = minor->dev))
goto out;

if (drm_device_is_unplugged(dev))
goto out;

old_fops = filp->f_op;
filp->f_op = fops_get(dev->driver->fops);
if (filp->f_op == NULL) {
Expand Down Expand Up @@ -579,6 +585,8 @@ int drm_release(struct inode *inode, struct file *filp)
retcode = -EBUSY;
} else
retcode = drm_lastclose(dev);
if (drm_device_is_unplugged(dev))
drm_put_dev(dev);
}
mutex_unlock(&drm_global_mutex);

Expand Down
3 changes: 3 additions & 0 deletions trunk/drivers/gpu/drm/drm_gem.c
Original file line number Diff line number Diff line change
Expand Up @@ -661,6 +661,9 @@ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
struct drm_hash_item *hash;
int ret = 0;

if (drm_device_is_unplugged(dev))
return -ENODEV;

mutex_lock(&dev->struct_mutex);

if (drm_ht_find_item(&mm->offset_hash, vma->vm_pgoff, &hash)) {
Expand Down
23 changes: 23 additions & 0 deletions trunk/drivers/gpu/drm/drm_stub.c
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,11 @@ int drm_put_minor(struct drm_minor **minor_p)
return 0;
}

static void drm_unplug_minor(struct drm_minor *minor)
{
drm_sysfs_device_remove(minor);
}

/**
* Called via drm_exit() at module unload time or when pci device is
* unplugged.
Expand Down Expand Up @@ -492,3 +497,21 @@ void drm_put_dev(struct drm_device *dev)
kfree(dev);
}
EXPORT_SYMBOL(drm_put_dev);

void drm_unplug_dev(struct drm_device *dev)
{
/* for a USB device */
if (drm_core_check_feature(dev, DRIVER_MODESET))
drm_unplug_minor(dev->control);
drm_unplug_minor(dev->primary);

mutex_lock(&drm_global_mutex);

drm_device_set_unplugged(dev);

if (dev->open_count == 0) {
drm_put_dev(dev);
}
mutex_unlock(&drm_global_mutex);
}
EXPORT_SYMBOL(drm_unplug_dev);
3 changes: 3 additions & 0 deletions trunk/drivers/gpu/drm/drm_vm.c
Original file line number Diff line number Diff line change
Expand Up @@ -680,6 +680,9 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
struct drm_device *dev = priv->minor->dev;
int ret;

if (drm_device_is_unplugged(dev))
return -ENODEV;

mutex_lock(&dev->struct_mutex);
ret = drm_mmap_locked(filp, vma);
mutex_unlock(&dev->struct_mutex);
Expand Down
16 changes: 16 additions & 0 deletions trunk/include/drm/drmP.h
Original file line number Diff line number Diff line change
Expand Up @@ -1170,6 +1170,8 @@ struct drm_device {
struct idr object_name_idr;
/*@} */
int switch_power_state;

atomic_t unplugged; /* device has been unplugged or gone away */
};

#define DRM_SWITCH_POWER_ON 0
Expand Down Expand Up @@ -1235,6 +1237,19 @@ static inline int drm_mtrr_del(int handle, unsigned long offset,
}
#endif

static inline void drm_device_set_unplugged(struct drm_device *dev)
{
smp_wmb();
atomic_set(&dev->unplugged, 1);
}

static inline int drm_device_is_unplugged(struct drm_device *dev)
{
int ret = atomic_read(&dev->unplugged);
smp_rmb();
return ret;
}

/******************************************************************/
/** \name Internal function definitions */
/*@{*/
Expand Down Expand Up @@ -1455,6 +1470,7 @@ extern void drm_master_put(struct drm_master **master);

extern void drm_put_dev(struct drm_device *dev);
extern int drm_put_minor(struct drm_minor **minor);
extern void drm_unplug_dev(struct drm_device *dev);
extern unsigned int drm_debug;

extern unsigned int drm_vblank_offdelay;
Expand Down

0 comments on commit 6fee277

Please sign in to comment.