diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-04-22 17:08:40 (GMT) |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-04-22 17:08:40 (GMT) |
commit | 3eb9992caff10b62cf0ed0bcb1667a58b13188fa (patch) | |
tree | abe4b4b586978773e2df21898eda611bc6eb822c /drivers/staging/comedi/comedi_fops.c | |
parent | e347fa5f4271769bc31fb462631c213aa3824588 (diff) | |
parent | a798c10faf62a505d24e5f6213fbaf904a39623f (diff) | |
download | linux-3eb9992caff10b62cf0ed0bcb1667a58b13188fa.tar.xz |
Merge 3.15-rc2 into staging-next
This resolves a bunch of merge errors with other fixes that are already
in Linus's tree.
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging/comedi/comedi_fops.c')
-rw-r--r-- | drivers/staging/comedi/comedi_fops.c | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index e283e6c..70545e6 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -1925,14 +1925,21 @@ static int comedi_mmap(struct file *file, struct vm_area_struct *vma) struct comedi_device *dev = file->private_data; struct comedi_subdevice *s; struct comedi_async *async; - struct comedi_buf_map *bm; + struct comedi_buf_map *bm = NULL; unsigned long start = vma->vm_start; unsigned long size; int n_pages; int i; int retval; - mutex_lock(&dev->mutex); + /* + * 'trylock' avoids circular dependency with current->mm->mmap_sem + * and down-reading &dev->attach_lock should normally succeed without + * contention unless the device is in the process of being attached + * or detached. + */ + if (!down_read_trylock(&dev->attach_lock)) + return -EAGAIN; if (!dev->attached) { dev_dbg(dev->class_dev, "no driver attached\n"); @@ -1972,7 +1979,9 @@ static int comedi_mmap(struct file *file, struct vm_area_struct *vma) } n_pages = size >> PAGE_SHIFT; - bm = async->buf_map; + + /* get reference to current buf map (if any) */ + bm = comedi_buf_map_from_subdev_get(s); if (!bm || n_pages > bm->n_pages) { retval = -EINVAL; goto done; @@ -1996,7 +2005,8 @@ static int comedi_mmap(struct file *file, struct vm_area_struct *vma) retval = 0; done: - mutex_unlock(&dev->mutex); + up_read(&dev->attach_lock); + comedi_buf_map_put(bm); /* put reference to buf map - okay if NULL */ return retval; } |